change rules :

- search command will search using pattern (None accepted)
 - ls command will display result of advanced search
This commit is contained in:
Bezleputh 2013-08-18 15:51:14 +02:00 committed by Romain Bignon
commit 33641953fc
12 changed files with 360 additions and 292 deletions

View file

@ -19,6 +19,7 @@
from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.capabilities.collection import ICapCollection, CollectionNotFound
from weboob.tools.ordereddict import OrderedDict from weboob.tools.ordereddict import OrderedDict
from weboob.tools.value import Value from weboob.tools.value import Value
from weboob.capabilities.job import ICapJob from weboob.capabilities.job import ICapJob
@ -28,7 +29,7 @@ from .job import AdeccoJobAdvert
__all__ = ['AdeccoBackend'] __all__ = ['AdeccoBackend']
class AdeccoBackend(BaseBackend, ICapJob): class AdeccoBackend(BaseBackend, ICapJob, ICapCollection):
NAME = 'adecco' NAME = 'adecco'
DESCRIPTION = u'adecco website' DESCRIPTION = u'adecco website'
MAINTAINER = u'Bezleputh' MAINTAINER = u'Bezleputh'
@ -46,229 +47,229 @@ class AdeccoBackend(BaseBackend, ICapJob):
}.iteritems())]) }.iteritems())])
searchCounty_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ searchCounty_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'000000' : u'Tous les départements', '000000': u'Tous les départements',
'95' : u'Ain (01)', '95': u'Ain (01)',
'81' : u'Aisne (02)', '81': u'Aisne (02)',
'8' : u'Allier (03)', '8': u'Allier (03)',
'89' : u'Alpes-de-Haute-Provence (04)', '89': u'Alpes-de-Haute-Provence (04)',
'91' : u'Alpes-Maritimes (06)', '91': u'Alpes-Maritimes (06)',
'104' : u'Andorre (991)', '104': u'Andorre (991)',
'96' : u'Ardèche (07)', '96': u'Ardèche (07)',
'29' : u'Ardennes (08)', '29': u'Ardennes (08)',
'66' : u'Ariège (09)', '66': u'Ariège (09)',
'30' : u'Aube (10)', '30': u'Aube (10)',
'54' : u'Aude (11)', '54': u'Aude (11)',
'67' : u'Aveyron (12)', '67': u'Aveyron (12)',
'1' : u'Bas-Rhin (67)', '1': u'Bas-Rhin (67)',
'92' : u'Bouches-du-Rhône (13)', '92': u'Bouches-du-Rhône (13)',
'12' : u'Calvados (14)', '12': u'Calvados (14)',
'9' : u'Cantal (15)', '9': u'Cantal (15)',
'85' : u'Charente (16)', '85': u'Charente (16)',
'86' : u'Charente-Maritime (17)', '86': u'Charente-Maritime (17)',
'23' : u'Cher (18)', '23': u'Cher (18)',
'59' : u'Corrèze (19)', '59': u'Corrèze (19)',
'33' : u'Corse-du-Sud (2A)', '33': u'Corse-du-Sud (2A)',
'15' : u'Côte-d\'Or (21)', '15': u'Côte-d\'Or (21)',
'19' : u'Côtes-d\'Armor (22)', '19': u'Côtes-d\'Armor (22)',
'60' : u'Creuse (23)', '60': u'Creuse (23)',
'87' : u'Deux-Sèvres (79)', '87': u'Deux-Sèvres (79)',
'3' : u'Dordogne (24)', '3': u'Dordogne (24)',
'40' : u'Doubs (25)', '40': u'Doubs (25)',
'97' : u'Drôme (26)', '97': u'Drôme (26)',
'49' : u'Essonne (91)', '49': u'Essonne (91)',
'44' : u'Eure (27)', '44': u'Eure (27)',
'24' : u'Eure-et-Loir (28)', '24': u'Eure-et-Loir (28)',
'20' : u'Finistère (29)', '20': u'Finistère (29)',
'55' : u'Gard (30)', '55': u'Gard (30)',
'69' : u'Gers (32)', '69': u'Gers (32)',
'4' : u'Gironde (33)', '4': u'Gironde (33)',
'35' : u'Guadeloupe (971)', '35': u'Guadeloupe (971)',
'37' : u'Guyane (973)', '37': u'Guyane (973)',
'34' : u'Haute-Corse (2B)', '34': u'Haute-Corse (2B)',
'68' : u'Haute-Garonne (31)', '68': u'Haute-Garonne (31)',
'10' : u'Haute-Loire (43)', '10': u'Haute-Loire (43)',
'32' : u'Haute-Marne (52)', '32': u'Haute-Marne (52)',
'90' : u'Hautes-Alpes (05)', '90': u'Hautes-Alpes (05)',
'42' : u'Haute-Saône (70)', '42': u'Haute-Saône (70)',
'102' : u'Haute-Savoie (74)', '102': u'Haute-Savoie (74)',
'71' : u'Hautes-Pyrénées (65)', '71': u'Hautes-Pyrénées (65)',
'61' : u'Haute-Vienne (87)', '61': u'Haute-Vienne (87)',
'2' : u'Haut-Rhin (68)', '2': u'Haut-Rhin (68)',
'50' : u'Hauts-de-Seine (92)', '50': u'Hauts-de-Seine (92)',
'56' : u'Hérault (34)', '56': u'Hérault (34)',
'21' : u'Ille-et-Vilaine (35)', '21': u'Ille-et-Vilaine (35)',
'25' : u'Indre (36)', '25': u'Indre (36)',
'26' : u'Indre-et-Loire (37)', '26': u'Indre-et-Loire (37)',
'98' : u'Isère (38)', '98': u'Isère (38)',
'41' : u'Jura (39)', '41': u'Jura (39)',
'38' : u'La Réunion (974)', '38': u'La Réunion (974)',
'5' : u'Landes (40)', '5': u'Landes (40)',
'99' : u'Loire (42)', '99': u'Loire (42)',
'76' : u'Loire-Atlantique (44)', '76': u'Loire-Atlantique (44)',
'28' : u'Loiret (45)', '28': u'Loiret (45)',
'27' : u'Loir-et-Cher (41)', '27': u'Loir-et-Cher (41)',
'70' : u'Lot (46)', '70': u'Lot (46)',
'6' : u'Lot-et-Garonne (47)', '6': u'Lot-et-Garonne (47)',
'57' : u'Lozère (48)', '57': u'Lozère (48)',
'77' : u'Maine-et-Loire (49)', '77': u'Maine-et-Loire (49)',
'13' : u'Manche (50)', '13': u'Manche (50)',
'31' : u'Marne (51)', '31': u'Marne (51)',
'36' : u'Martinique (972)', '36': u'Martinique (972)',
'78' : u'Mayenne (53)', '78': u'Mayenne (53)',
'39' : u'Mayotte (976)', '39': u'Mayotte (976)',
'62' : u'Meurthe-et-Moselle (54)', '62': u'Meurthe-et-Moselle (54)',
'63' : u'Meuse (55)', '63': u'Meuse (55)',
'105' : u'Monaco (992)', '105': u'Monaco (992)',
'22' : u'Morbihan (56)', '22': u'Morbihan (56)',
'64' : u'Moselle (57)', '64': u'Moselle (57)',
'16' : u'Nièvre (58)', '16': u'Nièvre (58)',
'74' : u'Nord (59)', '74': u'Nord (59)',
'109' : u'Nouvelle Calédonie (988)', '109': u'Nouvelle Calédonie (988)',
'83' : u'Oise (60)', '83': u'Oise (60)',
'14' : u'Orne (61)', '14': u'Orne (61)',
'46' : u'Paris (75)', '46': u'Paris (75)',
'75' : u'Pas-de-Calais (62)', '75': u'Pas-de-Calais (62)',
'108' : u'Polynésie (987)', '108': u'Polynésie (987)',
'11' : u'Puy-de-Dôme (63)', '11': u'Puy-de-Dôme (63)',
'7' : u'Pyrénées-Atlantiques (64)', '7': u'Pyrénées-Atlantiques (64)',
'58' : u'Pyrénées-Orientales (66)', '58': u'Pyrénées-Orientales (66)',
'100' : u'Rhône (69)', '100': u'Rhône (69)',
'17' : u'Saône-et-Loire (71)', '17': u'Saône-et-Loire (71)',
'79' : u'Sarthe (72)', '79': u'Sarthe (72)',
'101' : u'Savoie (73)', '101': u'Savoie (73)',
'47' : u'Seine-et-Marne (77)', '47': u'Seine-et-Marne (77)',
'45' : u'Seine-Maritime (76)', '45': u'Seine-Maritime (76)',
'51' : u'Seine-Saint-Denis (93)', '51': u'Seine-Saint-Denis (93)',
'84' : u'Somme (80)', '84': u'Somme (80)',
'107' : u'St Pierre et Miquelon (975)', '107': u'St Pierre et Miquelon (975)',
'106' : u'Suisse (993)', '106': u'Suisse (993)',
'72' : u'Tarn (81)', '72': u'Tarn (81)',
'73' : u'Tarn-et-Garonne (82)', '73': u'Tarn-et-Garonne (82)',
'43' : u'Territoire de Belfort (90)', '43': u'Territoire de Belfort (90)',
'103' : u'Tous pays (99)', '103': u'Tous pays (99)',
'52' : u'Val-de-Marne (94)', '52': u'Val-de-Marne (94)',
'53' : u'Val-d\'Oise (95)', '53': u'Val-d\'Oise (95)',
'93' : u'Var (83)', '93': u'Var (83)',
'94' : u'Vaucluse (84)', '94': u'Vaucluse (84)',
'80' : u'Vendée (85)', '80': u'Vendée (85)',
'88' : u'Vienne (86)', '88': u'Vienne (86)',
'65' : u'Vosges (88)', '65': u'Vosges (88)',
'18' : u'Yonne (89)', '18': u'Yonne (89)',
'48' : u'Yvelines (78)', '48': u'Yvelines (78)',
}.iteritems())]) }.iteritems())])
Region_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ Region_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'000000' : u'Toutes les régions', '000000': u'Toutes les régions',
'1' : u'Alsace', '1': u'Alsace',
'2' : u'Aquitaine', '2': u'Aquitaine',
'3' : u'Auvergne', '3': u'Auvergne',
'4' : u'Basse-Normandie', '4': u'Basse-Normandie',
'5' : u'Bourgogne', '5': u'Bourgogne',
'6' : u'Bretagne', '6': u'Bretagne',
'7' : u'Centre', '7': u'Centre',
'8' : u'Champagne-Ardenne', '8': u'Champagne-Ardenne',
'9' : u'Corse', '9': u'Corse',
'10' : u'DOM TOM', '10': u'DOM TOM',
'11' : u'Franche-Comté', '11': u'Franche-Comté',
'12' : u'Haute-Normandie', '12': u'Haute-Normandie',
'13' : u'île-de-France', '13': u'île-de-France',
'14' : u'Languedoc-Roussillon', '14': u'Languedoc-Roussillon',
'15' : u'Limousin', '15': u'Limousin',
'16' : u'Lorraine', '16': u'Lorraine',
'17' : u'Midi-Pyrénées', '17': u'Midi-Pyrénées',
'18' : u'Nord-Pas-de-Calais', '18': u'Nord-Pas-de-Calais',
'19' : u'Pays de la Loire', '19': u'Pays de la Loire',
'20' : u'Picardie', '20': u'Picardie',
'21' : u'Poitou-Charentes', '21': u'Poitou-Charentes',
'22' : u'Provence-Alpes-Côte d\'Azur', '22': u'Provence-Alpes-Côte d\'Azur',
'23' : u'Rhône-Alpes', '23': u'Rhône-Alpes',
'24' : u'International', '24': u'International',
}.iteritems())]) }.iteritems())])
JobCategory_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ JobCategory_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'000000' : u'Toutes catégories', '000000': u'Toutes catégories',
'1' : u'Accueil', '1': u'Accueil',
'4' : u'Achats ', '4': u'Achats ',
'32' : u'Aéronautique - Navale', '32': u'Aéronautique - Navale',
'9' : u'Agriculture - Viticulture - Pêche ', '9': u'Agriculture - Viticulture - Pêche ',
'33' : u'Agroalimentaire', '33': u'Agroalimentaire',
'15' : u'Architecture - Immobilier ', '15': u'Architecture - Immobilier ',
'13' : u'Assurance', '13': u'Assurance',
'41' : u'Autres ', '41': u'Autres ',
'57' : u'Autres', '57': u'Autres',
'60' : u'Autres', '60': u'Autres',
'3' : u'Autres Fonctions Administratives', '3': u'Autres Fonctions Administratives',
'11' : u'Banque - Finance ', '11': u'Banque - Finance ',
'14' : u'Bâtiment - Travaux Publics', '14': u'Bâtiment - Travaux Publics',
'58' : u'Chimie - Pétrochimie', '58': u'Chimie - Pétrochimie',
'20' : u'Commerce - Vente', '20': u'Commerce - Vente',
'59' : u'Commerce Appareillage', '59': u'Commerce Appareillage',
'42' : u'Conduite de véhicule', '42': u'Conduite de véhicule',
'8' : u'Direction Générale', '8': u'Direction Générale',
'37' : u'Direction informatique encadrement', '37': u'Direction informatique encadrement',
'53' : u'Direction, Encadrement', '53': u'Direction, Encadrement',
'50' : u'Directions, Cadres et Enseignement', '50': u'Directions, Cadres et Enseignement',
'28' : u'Electricité - Electronique - Automatisme', '28': u'Electricité - Electronique - Automatisme',
'22' : u'Environnement - HSE - Développement durable', '22': u'Environnement - HSE - Développement durable',
'10' : u'Espaces Verts - Exploitation Forestière', '10': u'Espaces Verts - Exploitation Forestière',
'38' : u'Etude et développement', '38': u'Etude et développement',
'43' : u'Exploitation de logistique - supply chain', '43': u'Exploitation de logistique - supply chain',
'39' : u'Exploitation, maintenance et support ', '39': u'Exploitation, maintenance et support ',
'12' : u'Gestion - Comptabilité', '12': u'Gestion - Comptabilité',
'21' : u'Grande et Moyenne Distribution', '21': u'Grande et Moyenne Distribution',
'25' : u'Hôtellerie', '25': u'Hôtellerie',
'47' : u'Imprimerie - Edition - Arts Graphiques', '47': u'Imprimerie - Edition - Arts Graphiques',
'16' : u'Industrie Pharmaceutique / Cosmétologique - Biotech', '16': u'Industrie Pharmaceutique / Cosmétologique - Biotech',
'5' : u'Juridique', '5': u'Juridique',
'29' : u'Maintenance - Entretien - SAV ', '29': u'Maintenance - Entretien - SAV ',
'44' : u'Manutention', '44': u'Manutention',
'46' : u'Marketing - Communication - Medias', '46': u'Marketing - Communication - Medias',
'30' : u'Mécanique Générale', '30': u'Mécanique Générale',
'27' : u'Métiers de bouche', '27': u'Métiers de bouche',
'23' : u'Nettoyage - Assainissement - Pressing', '23': u'Nettoyage - Assainissement - Pressing',
'34' : u'Nucléaire - Production d\'énergie', '34': u'Nucléaire - Production d\'énergie',
'18' : u'Pharmacie Officine / Hospit / Para-pharmacie', '18': u'Pharmacie Officine / Hospit / Para-pharmacie',
'35' : u'Plasturgie - Bois - Papier - Verre - Cuir - Textile', '35': u'Plasturgie - Bois - Papier - Verre - Cuir - Textile',
'31' : u'Production - Fabrication ', '31': u'Production - Fabrication ',
'6' : u'Qualité', '6': u'Qualité',
'17' : u'Recherche Clinique', '17': u'Recherche Clinique',
'49' : u'Rééducation, Radiologie, Appareillage, LAM', '49': u'Rééducation, Radiologie, Appareillage, LAM',
'7' : u'Ressources Humaines - Formation', '7': u'Ressources Humaines - Formation',
'26' : u'Restauration', '26': u'Restauration',
'2' : u'Secrétariat - Assistanat', '2': u'Secrétariat - Assistanat',
'51' : u'Secrétariat, Dentaire, Social, Esthétique et Autres', '51': u'Secrétariat, Dentaire, Social, Esthétique et Autres',
'24' : u'Sécurité - Premiers secours', '24': u'Sécurité - Premiers secours',
'36' : u'Sidérurgie - Métallurgie - Tuyauterie - Soudure', '36': u'Sidérurgie - Métallurgie - Tuyauterie - Soudure',
'48' : u'Soignants - Auxiliaires', '48': u'Soignants - Auxiliaires',
'55' : u'Spectacle - Audiovisuel', '55': u'Spectacle - Audiovisuel',
'40' : u'Systèmes et réseaux informatique et télécom', '40': u'Systèmes et réseaux informatique et télécom',
'52' : u'Téléconseil - Télévente - Autres', '52': u'Téléconseil - Télévente - Autres',
'54' : u'Tourisme - Loisirs', '54': u'Tourisme - Loisirs',
'45' : u'Transport', '45': u'Transport',
'19' : u'Vente, information et promotion du médicament', '19': u'Vente, information et promotion du médicament',
'56' : u'Autres', '56': u'Autres',
}.iteritems())]) }.iteritems())])
activityDomain_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({ activityDomain_choices = OrderedDict([(k, u'%s' % (v)) for k, v in sorted({
'000000' : u'Tous domaines d\'activité', '000000': u'Tous domaines d\'activité',
'1' : u'Accueil - Secrétariat - Fonctions Administratives', '1': u'Accueil - Secrétariat - Fonctions Administratives',
'2' : u'Achats - Juridique - Qualité - RH - Direction', '2': u'Achats - Juridique - Qualité - RH - Direction',
'3' : u'Agriculture - Viticulture - Pêche - Espaces Verts', '3': u'Agriculture - Viticulture - Pêche - Espaces Verts',
'4' : u'Automobile', '4': u'Automobile',
'5' : u'Banque - Finance - Gestion Comptabilité - Assurance', '5': u'Banque - Finance - Gestion Comptabilité - Assurance',
'6' : u'Bâtiment - Travaux Publics - Architecture - Immobilier', '6': u'Bâtiment - Travaux Publics - Architecture - Immobilier',
'13' : u'Bureaux d\'Etudes - Méthodes', '13': u'Bureaux d\'Etudes - Méthodes',
'8' : u'Commerce - Vente - Grande Distribution', '8': u'Commerce - Vente - Grande Distribution',
'9' : u'Environnement - Nettoyage - Sécurité', '9': u'Environnement - Nettoyage - Sécurité',
'10' : u'Hôtellerie - Restauration - Métiers de Bouche', '10': u'Hôtellerie - Restauration - Métiers de Bouche',
'11' : u'Industrie', '11': u'Industrie',
'12' : u'Informatique - Technologie de l\'Information', '12': u'Informatique - Technologie de l\'Information',
'14' : u'Logistique - Manutention - Transport', '14': u'Logistique - Manutention - Transport',
'15' : u'Marketing - Communication - Imprimerie - Edition', '15': u'Marketing - Communication - Imprimerie - Edition',
'16' : u'Médical - Paramédical - Esthétique', '16': u'Médical - Paramédical - Esthétique',
'7' : u'Pharmacie (Industrie, Officine) - Recherche clinique', '7': u'Pharmacie (Industrie, Officine) - Recherche clinique',
'17' : u'Télémarketing - Téléservices', '17': u'Télémarketing - Téléservices',
'18' : u'Tourisme - Loisirs - Spectacle - Audiovisuel', '18': u'Tourisme - Loisirs - Spectacle - Audiovisuel',
}.iteritems())]) }.iteritems())])
CONFIG = BackendConfig(Value('publication_date', label=u'Publication Date', choices=publicationDate_choices), CONFIG = BackendConfig(Value('publication_date', label=u'Publication Date', choices=publicationDate_choices),
@ -276,19 +277,30 @@ class AdeccoBackend(BaseBackend, ICapJob):
Value('region', label=u'Region', choices=Region_choices), Value('region', label=u'Region', choices=Region_choices),
Value('job_category', label=u'Job Category', choices=JobCategory_choices), Value('job_category', label=u'Job Category', choices=JobCategory_choices),
Value('activity_domain', label=u'Activity Domain', choices=activityDomain_choices), Value('activity_domain', label=u'Activity Domain', choices=activityDomain_choices),
) )
def search_job(self, pattern=None): def search_job(self, pattern=None):
with self.browser: with self.browser:
for advert in self.browser.search_job(pattern, for advert in self.browser.search_job(pattern):
publication_date=int(self.config['publication_date'].get()),
conty=int(self.config['conty'].get()),
region=int(self.config['region'].get()),
job_category=int(self.config['job_category'].get()),
activity_domain=int(self.config['activity_domain'].get())
):
yield advert yield advert
def iter_resources(self, objs, split_path):
with self.browser:
collection = self.get_collection(objs, split_path)
if collection.path_level == 0:
for advert in self.browser.advanced_search_job(publication_date=int(self.config['publication_date'].get()),
conty=int(self.config['conty'].get()),
region=int(self.config['region'].get()),
job_category=int(self.config['job_category'].get()),
activity_domain=int(self.config['activity_domain'].get())
):
yield advert
def validate_collection(self, objs, collection):
if collection.path_level == 0:
return
raise CollectionNotFound(collection.split_path)
def get_job_advert(self, _id, advert=None): def get_job_advert(self, _id, advert=None):
with self.browser: with self.browser:
return self.browser.get_job_advert(_id, advert) return self.browser.get_job_advert(_id, advert)

View file

@ -36,18 +36,22 @@ class AdeccoBrowser(BaseBrowser):
'%s://%s/trouver-un-emploi/Pages/Details-de-l-Offre/(.*?)/(.*?).aspx\?IOF=(.*?)$' % (PROTOCOL, DOMAIN): AdvertPage, '%s://%s/trouver-un-emploi/Pages/Details-de-l-Offre/(.*?)/(.*?).aspx\?IOF=(.*?)$' % (PROTOCOL, DOMAIN): AdvertPage,
} }
def search_job(self, pattern = None, publication_date = None, conty = None, region = None, job_category = None, activity_domain = None): def search_job(self, pattern=None, publication_date=None, conty=None, region=None, job_category=None, activity_domain=None):
if pattern: self.location('%s://%s/trouver-un-emploi/Pages/Offres-d-emploi.aspx?keywords=%s'
self.location('%s://%s/trouver-un-emploi/Pages/Offres-d-emploi.aspx?keywords=%s' % (self.PROTOCOL, self.DOMAIN, pattern.replace(' ', '+'))) % (self.PROTOCOL, self.DOMAIN, pattern.replace(' ', '+')))
else: assert self.is_on_page(SearchPage)
data = { return self.page.iter_job_adverts()
'publicationDate': publication_date,
'department' : conty, def advanced_search_job(self, publication_date=None, conty=None, region=None, job_category=None, activity_domain=None):
'region' : region, data = {
'jobCategory' : job_category, 'publicationDate': publication_date,
'activityDomain' : activity_domain, 'department': conty,
} 'region': region,
self.location('%s://%s/trouver-un-emploi/Pages/Offres-d-emploi.aspx?%s' % (self.PROTOCOL, self.DOMAIN, urllib.urlencode(data))) 'jobCategory': job_category,
'activityDomain': activity_domain,
}
self.location('%s://%s/trouver-un-emploi/Pages/Offres-d-emploi.aspx?%s'
% (self.PROTOCOL, self.DOMAIN, urllib.urlencode(data)))
assert self.is_on_page(SearchPage) assert self.is_on_page(SearchPage)
return self.page.iter_job_adverts() return self.page.iter_job_adverts()

View file

@ -24,8 +24,14 @@ from weboob.tools.test import BackendTest
class AdeccoTest(BackendTest): class AdeccoTest(BackendTest):
BACKEND = 'adecco' BACKEND = 'adecco'
def test_adecco(self): def test_adecco_search(self):
l = list(self.backend.search_job(u'valet de chambre')) l = list(self.backend.search_job(u'valet de chambre'))
assert len(l) assert len(l)
advert = self.backend.get_job_advert(l[0].id, None) advert = self.backend.get_job_advert(l[0].id, None)
self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url)) self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url))
def test_adecco_advanced_search(self):
l = list(self.backend.iter_resources([], []))
assert len(l)
advert = self.backend.get_job_advert(l[0].id, None)
self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url))

View file

@ -19,6 +19,7 @@
from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.capabilities.collection import ICapCollection, CollectionNotFound
from weboob.capabilities.job import ICapJob from weboob.capabilities.job import ICapJob
from weboob.tools.ordereddict import OrderedDict from weboob.tools.ordereddict import OrderedDict
from weboob.tools.value import Value from weboob.tools.value import Value
@ -28,7 +29,7 @@ from .job import ApecJobAdvert
__all__ = ['ApecBackend'] __all__ = ['ApecBackend']
class ApecBackend(BaseBackend, ICapJob): class ApecBackend(BaseBackend, ICapJob, ICapCollection):
NAME = 'apec' NAME = 'apec'
DESCRIPTION = u'apec website' DESCRIPTION = u'apec website'
MAINTAINER = u'Bezleputh' MAINTAINER = u'Bezleputh'
@ -229,16 +230,27 @@ class ApecBackend(BaseBackend, ICapJob):
def search_job(self, pattern=None): def search_job(self, pattern=None):
with self.browser: with self.browser:
for job_advert in self.browser.search_job(pattern=pattern, for job_advert in self.browser.search_job(pattern=pattern):
region=self.config['place'].get(),
fonction=self.config['fonction'].get(),
secteur=self.config['secteur'].get(),
salaire=self.config['salaire'].get(),
contrat=self.config['contrat'].get(),
limit_date=self.config['limit_date'].get(),
level=self.config['level'].get()):
yield job_advert yield job_advert
def iter_resources(self, objs, split_path):
with self.browser:
collection = self.get_collection(objs, split_path)
if collection.path_level == 0:
for job_advert in self.browser.advanced_search_job(region=self.config['place'].get(),
fonction=self.config['fonction'].get(),
secteur=self.config['secteur'].get(),
salaire=self.config['salaire'].get(),
contrat=self.config['contrat'].get(),
limit_date=self.config['limit_date'].get(),
level=self.config['level'].get()):
yield job_advert
def validate_collection(self, objs, collection):
if collection.path_level == 0:
return
raise CollectionNotFound(collection.split_path)
def get_job_advert(self, _id, advert=None): def get_job_advert(self, _id, advert=None):
with self.browser: with self.browser:
return self.browser.get_job_advert(_id, advert) return self.browser.get_job_advert(_id, advert)

View file

@ -38,22 +38,24 @@ class ApecBrowser(BaseBrowser):
'http://cadres.apec.fr/offres-emploi-cadres/offres-emploi-cadres/\d*_\d*_\d*_(.*?)________(.*?).html(.*?)': AdvertPage, 'http://cadres.apec.fr/offres-emploi-cadres/offres-emploi-cadres/\d*_\d*_\d*_(.*?)________(.*?).html(.*?)': AdvertPage,
} }
def search_job(self, pattern=None, region=None, fonction=None, secteur=None, salaire=None, contrat=None, limit_date=None, level=None): def search_job(self, pattern=None):
if pattern: self.location('http://cadres.apec.fr/MesOffres/RechercheOffres/ApecRechercheOffre.jsp?keywords=%s'
self.location('http://cadres.apec.fr/MesOffres/RechercheOffres/ApecRechercheOffre.jsp?keywords=%s' % pattern.replace(' ', '+'))
% pattern.replace(' ', '+')) assert self.is_on_page(SearchPage)
else: return self.page.iter_job_adverts()
self.location(
'http://cadres.apec.fr/liste-offres-emploi-cadres/8_0___%s_%s_%s_%s_%s_%s_%s_offre-d-emploi.html' def advanced_search_job(self, region=None, fonction=None, secteur=None, salaire=None, contrat=None, limit_date=None, level=None):
% ( self.location(
region, 'http://cadres.apec.fr/liste-offres-emploi-cadres/8_0___%s_%s_%s_%s_%s_%s_%s_offre-d-emploi.html'
fonction, % (
secteur, region,
salaire, fonction,
level, secteur,
limit_date, salaire,
contrat level,
)) limit_date,
contrat
))
assert self.is_on_page(SearchPage) assert self.is_on_page(SearchPage)
return self.page.iter_job_adverts() return self.page.iter_job_adverts()

View file

@ -24,8 +24,14 @@ from weboob.tools.test import BackendTest
class ApecTest(BackendTest): class ApecTest(BackendTest):
BACKEND = 'apec' BACKEND = 'apec'
def test_apec(self): def test_apec_search(self):
l = list(self.backend.search_job(u'informaticien')) l = list(self.backend.search_job(u'informaticien'))
assert len(l) assert len(l)
advert = self.backend.get_job_advert(l[0].id, None) advert = self.backend.get_job_advert(l[0].id, None)
self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url)) self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url))
def test_apec_advanced_search(self):
l = list(self.backend.iter_resources([], []))
assert len(l)
advert = self.backend.get_job_advert(l[0].id, None)
self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url))

View file

@ -18,6 +18,7 @@
# along with weboob. If not, see <http://www.gnu.org/licenses/>. # along with weboob. If not, see <http://www.gnu.org/licenses/>.
from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.capabilities.collection import ICapCollection, CollectionNotFound
from weboob.tools.ordereddict import OrderedDict from weboob.tools.ordereddict import OrderedDict
from weboob.tools.value import Value from weboob.tools.value import Value
from weboob.capabilities.job import ICapJob from weboob.capabilities.job import ICapJob
@ -28,7 +29,7 @@ from .job import LolixJobAdvert
__all__ = ['LolixBackend'] __all__ = ['LolixBackend']
class LolixBackend(BaseBackend, ICapJob): class LolixBackend(BaseBackend, ICapJob, ICapCollection):
NAME = 'lolix' NAME = 'lolix'
DESCRIPTION = u'Lolix French free software employment website' DESCRIPTION = u'Lolix French free software employment website'
MAINTAINER = u'Bezleputh' MAINTAINER = u'Bezleputh'
@ -137,14 +138,20 @@ class LolixBackend(BaseBackend, ICapJob):
Value('contrat', label=u'Contrat', choices=contrat_choices), Value('contrat', label=u'Contrat', choices=contrat_choices),
Value('limit_date', label=u'Date limite', choices=limit_date_choices)) Value('limit_date', label=u'Date limite', choices=limit_date_choices))
def search_job(self, pattern=None): def iter_resources(self, objs, split_path):
with self.browser: with self.browser:
if not pattern: collection = self.get_collection(objs, split_path)
for advert in self.browser.search_job(region=self.config['region'].get(), if collection.path_level == 0:
poste=self.config['poste'].get(), for advert in self.browser.advanced_search_job(region=self.config['region'].get(),
contrat=int(self.config['contrat'].get()), poste=self.config['poste'].get(),
limit_date=self.config['limit_date'].get()): contrat=int(self.config['contrat'].get()),
yield advert limit_date=self.config['limit_date'].get()):
yield advert
def validate_collection(self, objs, collection):
if collection.path_level == 0:
return
raise CollectionNotFound(collection.split_path)
def get_job_advert(self, _id, advert=None): def get_job_advert(self, _id, advert=None):
with self.browser: with self.browser:

View file

@ -36,7 +36,7 @@ class LolixBrowser(BaseBrowser):
'%s://%s/offre.php\?id=(?P<id>.+)' % (PROTOCOL, DOMAIN): AdvertPage, '%s://%s/offre.php\?id=(?P<id>.+)' % (PROTOCOL, DOMAIN): AdvertPage,
} }
def search_job(self, region=None, poste=None, contrat=None, limit_date=None): def advanced_search_job(self, region=None, poste=None, contrat=None, limit_date=None):
data = { data = {
'mode': 'find', 'mode': 'find',
'page': '0', 'page': '0',

View file

@ -24,8 +24,8 @@ from weboob.tools.test import BackendTest
class LolixTest(BackendTest): class LolixTest(BackendTest):
BACKEND = 'lolix' BACKEND = 'lolix'
def test_lolix(self): def test_lolix_advanced_search(self):
l = list(self.backend.search_job()) l = list(self.backend.iter_resources([], []))
assert len(l) assert len(l)
advert = self.backend.get_job_advert(l[0].id, l[0]) advert = self.backend.get_job_advert(l[0].id, l[0])
self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url)) self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url))

View file

@ -19,6 +19,7 @@
from weboob.tools.backend import BaseBackend, BackendConfig from weboob.tools.backend import BaseBackend, BackendConfig
from weboob.capabilities.collection import ICapCollection, CollectionNotFound
from weboob.capabilities.job import ICapJob from weboob.capabilities.job import ICapJob
from weboob.tools.value import Value from weboob.tools.value import Value
from weboob.tools.ordereddict import OrderedDict from weboob.tools.ordereddict import OrderedDict
@ -29,7 +30,7 @@ from .job import PopolemploiJobAdvert
__all__ = ['PopolemploiBackend'] __all__ = ['PopolemploiBackend']
class PopolemploiBackend(BaseBackend, ICapJob): class PopolemploiBackend(BaseBackend, ICapJob, ICapCollection):
NAME = 'popolemploi' NAME = 'popolemploi'
DESCRIPTION = u'Pole Emploi website' DESCRIPTION = u'Pole Emploi website'
MAINTAINER = u'Bezleputh' MAINTAINER = u'Bezleputh'
@ -202,10 +203,20 @@ class PopolemploiBackend(BaseBackend, ICapJob):
def search_job(self, pattern=None): def search_job(self, pattern=None):
with self.browser: with self.browser:
return self.browser.search_job(pattern=pattern, return self.browser.search_job(pattern=pattern)
metier=self.config['metier'].get(),
place=self.config['place'].get(), def iter_resources(self, objs, split_path):
contrat=self.config['contrat'].get()) with self.browser:
collection = self.get_collection(objs, split_path)
if collection.path_level == 0:
return self.browser.advanced_search_job(metier=self.config['metier'].get(),
place=self.config['place'].get(),
contrat=self.config['contrat'].get())
def validate_collection(self, objs, collection):
if collection.path_level == 0:
return
raise CollectionNotFound(collection.split_path)
def get_job_advert(self, _id, advert=None): def get_job_advert(self, _id, advert=None):
with self.browser: with self.browser:

View file

@ -39,19 +39,21 @@ class PopolemploiBrowser(BaseBrowser):
} }
def search_job(self, pattern=None, metier=None, place=None, contrat=None): def search_job(self, pattern=None, metier=None, place=None, contrat=None):
if pattern: self.location('http://offre.pole-emploi.fr/resultat?offresPartenaires=true&libMetier=%s'
self.location('http://offre.pole-emploi.fr/resultat?offresPartenaires=true&libMetier=%s' % pattern.replace(' ', '+'))
% pattern.replace(' ', '+')) assert self.is_on_page(SearchPage)
else: return self.page.iter_job_adverts()
data = {
't:formdata': 'H4sIAAAAAAAAAJVSwUocQRAtJ1HBPSQonoLIEo1BpPeiErJ42AQ8LYlkMRdPPW3N2trT3emu2Vkv3vIb+YIg5Bs85JZ/yAfkmlMO6d5hR0UY1oEZpqtfVb33qr7/gfnyDew7FGfowmuyzKHvDGRulcwk4luuFLoROq94jeIjrgWid3CUOWaR5YIJk+eFZsQtenKXTJ7lMWaNRk2e9aW+GBRpLqk3QvHeaMIx4caRMwK9n9x4L40+/vrj+qDVXksgOYFFUeEIVk7656FrR3E97HxMz1FQtw8tVJiH8h94jgTLdyADclIPu2MHz2OQxSCr8uD2GVtL8GKi8HNQ2Oefpgp7lcJyB7YbvMHwZ2QNCH7sGTdk3PJwqq3YCz44VDJlKffIemkIckGHEtXpxgCpsJvHN63fqz//JTAXREXRzqgo6gtcQTKO3ycEz6p2NcdHk+s9ltyD6dxcn+5mf7/9SoJ3E1ZlG9YbOCiJhY/ABYKn8TADPsKXypfQbsD5MHhB08oL1XGmnKr6Fmw2IOsrF0w7nHXD35mCjK52vGmv5+7v7b0RL922Ll/DqwaOljtCzcN8/dSG1p3Y7NkTQ/4DH0zoXggEAAA=', def advanced_search_job(self, metier=None, place=None, contrat=None):
'emploiRecherche': metier, data = {
'lieu': place, 't:formdata': 'H4sIAAAAAAAAAJVSwUocQRAtJ1HBPSQonoLIEo1BpPeiErJ42AQ8LYlkMRdPPW3N2trT3emu2Vkv3vIb+YIg5Bs85JZ/yAfkmlMO6d5hR0UY1oEZpqtfVb33qr7/gfnyDew7FGfowmuyzKHvDGRulcwk4luuFLoROq94jeIjrgWid3CUOWaR5YIJk+eFZsQtenKXTJ7lMWaNRk2e9aW+GBRpLqk3QvHeaMIx4caRMwK9n9x4L40+/vrj+qDVXksgOYFFUeEIVk7656FrR3E97HxMz1FQtw8tVJiH8h94jgTLdyADclIPu2MHz2OQxSCr8uD2GVtL8GKi8HNQ2Oefpgp7lcJyB7YbvMHwZ2QNCH7sGTdk3PJwqq3YCz44VDJlKffIemkIckGHEtXpxgCpsJvHN63fqz//JTAXREXRzqgo6gtcQTKO3ycEz6p2NcdHk+s9ltyD6dxcn+5mf7/9SoJ3E1ZlG9YbOCiJhY/ABYKn8TADPsKXypfQbsD5MHhB08oL1XGmnKr6Fmw2IOsrF0w7nHXD35mCjK52vGmv5+7v7b0RL922Ll/DqwaOljtCzcN8/dSG1p3Y7NkTQ/4DH0zoXggEAAA=',
'select': contrat, 'emploiRecherche': metier,
'partenaires': 'on', 'lieu': place,
} 'select': contrat,
self.location('http://candidat.pole-emploi.fr/candidat/rechercheoffres/simplifiee.recherche', 'partenaires': 'on',
urllib.urlencode(data)) }
self.location('http://candidat.pole-emploi.fr/candidat/rechercheoffres/simplifiee.recherche',
urllib.urlencode(data))
assert self.is_on_page(SearchPage) assert self.is_on_page(SearchPage)
return self.page.iter_job_adverts() return self.page.iter_job_adverts()

View file

@ -24,8 +24,14 @@ from weboob.tools.test import BackendTest
class PopolemploiTest(BackendTest): class PopolemploiTest(BackendTest):
BACKEND = 'popolemploi' BACKEND = 'popolemploi'
def test_popolemploi(self): def test_popolemploi_search(self):
l = list(self.backend.search_job('infographiste')) l = list(self.backend.search_job('infographiste'))
assert len(l) assert len(l)
advert = self.backend.get_job_advert(l[0].id, l[0]) advert = self.backend.get_job_advert(l[0].id, l[0])
self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url)) self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url))
def test_popolemploi_advanced_search(self):
l = list(self.backend.iter_resources([], []))
assert len(l)
advert = self.backend.get_job_advert(l[0].id, l[0])
self.assertTrue(advert.url, 'URL for announce "%s" not found: %s' % (advert.id, advert.url))