class SeLogerBrowser(PagesBrowser): BASEURL = 'https://www.seloger.com' PROFILE = Android() cities = URL( r'https://autocomplete.svc.groupe-seloger.com/auto/complete/0/Ville/6\?text=(?P<pattern>.*)', CitiesPage) search = URL( r'/list.html\?(?P<query>.*)&LISTING-LISTpg=(?P<page_number>\d+)', SearchResultsPage) housing = URL(r'/(?P<_id>.+)/detail.htm', r'/annonces/.+', HousingPage) housing_detail = URL( r'detail,json,caracteristique_bien.json\?idannonce=(?P<_id>\d+)', HousingJsonPage) captcha = URL(r'http://validate.perfdrive.com', ErrorPage) def search_geo(self, pattern): return self.cities.open(pattern=pattern).iter_cities() def search_housings(self, _type, cities, nb_rooms, area_min, area_max, cost_min, cost_max, house_types, advert_types): price = '{}/{}'.format(cost_min or 'NaN', cost_max or 'Nan') surface = '{}/{}'.format(area_min or 'Nan', area_max or 'Nan') rooms = '' if nb_rooms: rooms = '&rooms={}'.format(nb_rooms if nb_rooms <= 5 else 5) viager = "" if _type not in TYPES: raise TypeNotSupported() elif _type != POSTS_TYPES.VIAGER: _type = '{}'.format(TYPES.get(_type)) viager = "&natures=1,2,4" else: _type = TYPES.get(_type) places = '|'.join(['{{ci:{}}}'.format(c) for c in cities]) places = '[{}]'.format(places) ret = ','.join([RET.get(t) for t in house_types if t in RET]) query = "projects={}{}&places={}&types={}&price={}&surface={}{}&enterprise=0&qsVersion=1.0"\ .format(_type, viager, places, ret, price, surface, rooms) return self.search.go(query=query, page_number=1).iter_housings( query_type=_type, advert_types=advert_types, ret=ret) def get_housing(self, _id, obj=None): return self.housing.go(_id=_id).get_housing(obj=obj) def get_housing_detail(self, obj): return self.housing_detail.go(_id=obj.id).get_housing(obj=obj)
class SeLogerBrowser(PagesBrowser): BASEURL = 'http://www.seloger.com' PROFILE = Android() cities = URL('js,ajax,villequery_v3.htm\?ville=(?P<pattern>.*)', CitiesPage) search = URL('http://ws.seloger.com/search.xml\?(?P<request>.*)', SearchResultsPage) housing = URL( 'http://ws.seloger.com/annonceDetail.xml\?idAnnonce=(?P<_id>\d+)&noAudiotel=(?P<noAudiotel>\d)', HousingPage) def search_geo(self, pattern): return self.cities.open(pattern=pattern).iter_cities() def search_housings(self, type, cities, nb_rooms, area_min, area_max, cost_min, cost_max, house_types, advert_types): if type not in TYPES: raise TypeNotSupported() data = { 'ci': ','.join(cities), 'idtt': TYPES.get(type, 1), 'org': 'advanced_search', 'surfacemax': area_max or '', 'surfacemin': area_min or '', 'tri': 'd_dt_crea', } if type == POSTS_TYPES.SALE: data['pxmax'] = cost_max or '' data['pxmin'] = cost_min or '' else: data['px_loyermax'] = cost_max or '' data['px_loyermin'] = cost_min or '' if nb_rooms: data['nb_pieces'] = nb_rooms ret = [] for house_type in house_types: if house_type in RET: ret.append(RET.get(house_type)) if ret: data['idtypebien'] = ','.join(ret) if (len(advert_types) == 1 and advert_types[0] == ADVERT_TYPES.PROFESSIONAL): data['SI_PARTICULIER'] = 0 elif (len(advert_types) == 1 and advert_types[0] == ADVERT_TYPES.PERSONAL): data['SI_PARTICULIER'] = 1 return self.search.go(request=urlencode(data)).iter_housings( query_type=type) def get_housing(self, _id, obj=None): return self.housing.go(_id=_id, noAudiotel=1).get_housing(obj=obj)
class SeLogerBrowser(PagesBrowser): BASEURL = 'http://www.seloger.com' PROFILE = Android() cities = URL('js,ajax,villequery_v3.htm\?ville=(?P<pattern>.*)', CitiesPage) search = URL('http://ws.seloger.com/search.xml\?(?P<request>.*)', SearchResultsPage) housing = URL('http://ws.seloger.com/annonceDetail.xml\?idAnnonce=(?P<_id>\d+)&noAudiotel=(?P<noAudiotel>\d)', HousingPage) def search_geo(self, pattern): return self.cities.open(pattern=pattern.encode('utf-8')).iter_cities() TYPES = {Query.TYPE_RENT: 1, Query.TYPE_SALE: 2 } RET = {Query.HOUSE_TYPES.HOUSE: '2', Query.HOUSE_TYPES.APART: '1', Query.HOUSE_TYPES.LAND: '4', Query.HOUSE_TYPES.PARKING: '3', Query.HOUSE_TYPES.OTHER: '10'} def search_housings(self, type, cities, nb_rooms, area_min, area_max, cost_min, cost_max, house_types): data = {'ci': ','.join(cities), 'idtt': self.TYPES.get(type, 1), 'org': 'advanced_search', 'surfacemax': area_max or '', 'surfacemin': area_min or '', 'tri': 'd_dt_crea', } if type == Query.TYPE_SALE: data['pxmax'] = cost_max or '' data['pxmin'] = cost_min or '' else: data['px_loyermax'] = cost_max or '' data['px_loyermin'] = cost_min or '' if nb_rooms: data['nb_pieces'] = nb_rooms ret = [] for house_type in house_types: if house_type in self.RET: ret.append(self.RET.get(house_type)) if ret: data['idtypebien'] = ','.join(ret) return self.search.go(request=urllib.urlencode(data)).iter_housings() def get_housing(self, _id, obj=None): return self.housing.go(_id=_id, noAudiotel=1).get_housing(obj=obj)
class ColissimoBrowser(DomainBrowser): BASEURL = 'http://www.laposte.fr' PROFILE = Android() api_key = '6b252eb30d3afb15c47cf3fccee3dc17352dc2d6' def get_tracking_info(self, _id): json_data = self.open( '/outilsuivi/web/suiviInterMetiers.php?key=%s&method=json&code=%s' % (self.api_key, _id)).text if json_data is None: raise BrowserBanned( 'You are banned of the colissimo API (too many requests from your IP)' ) return json.loads(json_data)
class FacebookBrowser(DomainBrowser): BASEURL = 'https://graph.facebook.com' PROFILE = Android() CLIENT_ID = "464891386855067" access_token = None info = None def login(self, username, password): self.location( 'https://www.facebook.com/v2.6/dialog/oauth?redirect_uri=fb464891386855067%3A%2F%2Fauthorize%2F&display=touch&state=%7B%22challenge%22%3A%22IUUkEUqIGud332lfu%252BMJhxL4Wlc%253D%22%2C%220_auth_logger_id%22%3A%2230F06532-A1B9-4B10-BB28-B29956C71AB1%22%2C%22com.facebook.sdk_client_state%22%3Atrue%2C%223_method%22%3A%22sfvc_auth%22%7D&scope=user_birthday%2Cuser_photos%2Cuser_education_history%2Cemail%2Cuser_relationship_details%2Cuser_friends%2Cuser_work_history%2Cuser_likes&response_type=token%2Csigned_request&default_audience=friends&return_scopes=true&auth_type=rerequest&client_id=' + self.CLIENT_ID + '&ret=login&sdk=ios&logger_id=30F06532-A1B9-4B10-BB28-B29956C71AB1&ext=1470840777&hash=AeZqkIcf-NEW6vBd' ) page = HTMLPage(self, self.response) form = page.get_form() form['email'] = username form['pass'] = password form.submit(allow_redirects=False) if 'Location' not in self.response.headers: raise BrowserIncorrectPassword() self.location(self.response.headers['Location']) page = HTMLPage(self, self.response) if len(page.doc.xpath('//td/div[has-class("s")]')) > 0: raise BrowserIncorrectPassword( CleanText('//td/div[has-class("s")]')(page.doc)) form = page.get_form(nr=0, submit='//input[@name="__CONFIRM__"]') form.submit(allow_redirects=False) m = re.search('access_token=([^&]+)&', self.response.headers['Location']) if m: self.access_token = m.group(1) else: raise ParseError('Unable to find access_token') self.info = self.request('/me') def request(self, url, *args, **kwargs): url += '?access_token=' + self.access_token self.location(self.absurl(url, base=True), *args, **kwargs) return json.loads(self.response.content)
class S2eBrowser(LoginBrowser): PROFILE = Android() CTCC = "" LANG = "FR" sessionId = None loginp = URL('/$', LoginPage) calcp = URL( '/s2e_services/restServices/calculetteService/grillemdp\?uuid=(?P<uuid>)', CalcPage) profilp = URL('/s2e_services/restServices/authentification/loginS', ProfilPage) accountsp = URL('/s2e_services/restServices/situationCompte', AccountsPage) historyp = URL('/s2e_services/restServices/listeOperation', HistoryPage) i18np = URL('/(?P<lang1>.*)/LANG/(?P<lang2>.*).json', I18nPage) def __init__(self, url, username, password, *args, **kwargs): super(S2eBrowser, self).__init__(username, password, *args, **kwargs) self.BASEURL = "https://" + url def do_login(self): self.logger.debug('call Browser.do_login') self.loginp.stay_or_go() self.page.login(self.username, self.password) if self.sessionId is None: raise BrowserIncorrectPassword() @need_login def get_accounts_list(self): data = { 'clang': self.LANG, 'ctcc': self.CTCC, 'login': self.username, 'session': self.sessionId } for k, fond in self.accountsp.open(data=data).get_list().items(): a = Account() a.id = k a.type = Account.TYPE_LOAN a.balance = Decimal(fond["montantValeurEuro"]).quantize( Decimal('.01')) a.label = fond["libelleSupport"] a.currency = u"EUR" # Don't find any possbility to get that from configuration. yield a @need_login def iter_history(self, account): # Load i18n for type translation self.i18np.open(lang1=self.LANG, lang2=self.LANG).load_i18n() # For now detail for each account is not available. History is global for all accounts and very simplist data = { 'clang': self.LANG, 'ctcc': self.CTCC, 'login': self.username, 'session': self.sessionId } for trans in self.historyp.open(data=data).get_transactions(): t = Transaction() t.id = trans["referenceOperationIndividuelle"] t.date = datetime.strptime(trans["dateHeureSaisie"], "%d/%m/%Y") t.rdate = datetime.strptime(trans["dateHeureSaisie"], "%d/%m/%Y") t.type = Transaction.TYPE_DEPOSIT if trans[ "montantNetEuro"] > 0 else Transaction.TYPE_PAYBACK t.raw = trans["typeOperation"] t.label = self.i18n["OPERATION_TYPE_" + trans["casDeGestion"]] t.amount = Decimal(trans["montantNetEuro"]).quantize( Decimal('.01')) yield t
class AllocineBrowser(APIBrowser): PROFILE = Android() PARTNER_KEY = '100043982026' SECRET_KEY = b'29d185d98c984a359e6e6f26a0474269' def __do_request(self, method, params): params.append(("sed", time.strftime('%Y%m%d', time.localtime()))) params.append( ("sig", base64.b64encode( hashlib.sha1( self.SECRET_KEY + urlencode(params).encode('utf-8')).digest()).decode())) return self.request('http://api.allocine.fr/rest/v3/{}'.format(method), params=params) def iter_movies(self, pattern): params = [('partner', self.PARTNER_KEY), ('q', pattern), ('format', 'json'), ('filter', 'movie')] jres = self.__do_request('search', params) if jres is None: return if 'movie' not in jres['feed']: return for m in jres['feed']['movie']: tdesc = u'' if 'title' in m: tdesc += '%s' % m['title'] if 'productionYear' in m: tdesc += ' ; %s' % m['productionYear'] elif 'release' in m: tdesc += ' ; %s' % m['release']['releaseDate'] if 'castingShort' in m and 'actors' in m['castingShort']: tdesc += ' ; %s' % m['castingShort']['actors'] short_description = tdesc.strip('; ') thumbnail_url = NotAvailable if 'poster' in m: thumbnail_url = unicode(m['poster']['href']) movie = Movie(m['code'], unicode(m['originalTitle'])) movie.other_titles = NotLoaded movie.release_date = NotLoaded movie.duration = NotLoaded movie.short_description = short_description movie.pitch = NotLoaded movie.country = NotLoaded movie.note = NotLoaded movie.roles = NotLoaded movie.all_release_dates = NotLoaded movie.thumbnail_url = thumbnail_url yield movie def iter_persons(self, pattern): params = [('partner', self.PARTNER_KEY), ('q', pattern), ('format', 'json'), ('filter', 'person')] jres = self.__do_request('search', params) if jres is None: return if 'person' not in jres['feed']: return for p in jres['feed']['person']: thumbnail_url = NotAvailable if 'picture' in p: thumbnail_url = unicode(p['picture']['href']) person = Person(p['code'], unicode(p['name'])) desc = u'' if 'birthDate' in p: desc += '(%s), ' % p['birthDate'] if 'activity' in p: for a in p['activity']: desc += '%s, ' % a['$'] person.real_name = NotLoaded person.birth_place = NotLoaded person.birth_date = NotLoaded person.death_date = NotLoaded person.gender = NotLoaded person.nationality = NotLoaded person.short_biography = NotLoaded person.short_description = desc.strip(', ') person.roles = NotLoaded person.thumbnail_url = thumbnail_url yield person def get_movie(self, id): params = [('partner', self.PARTNER_KEY), ('code', id), ('profile', 'large'), ('mediafmt', 'mp4-lc'), ('filter', 'movie'), ('striptags', 'synopsis,synopsisshort'), ('format', 'json')] jres = self.__do_request('movie', params) if jres is not None: if 'movie' in jres: jres = jres['movie'] else: return None else: return None title = NotAvailable duration = NotAvailable release_date = NotAvailable pitch = NotAvailable country = NotAvailable note = NotAvailable short_description = NotAvailable thumbnail_url = NotAvailable other_titles = [] genres = [] roles = {} if 'originalTitle' not in jres: return title = unicode(jres['originalTitle'].strip()) if 'poster' in jres: thumbnail_url = unicode(jres['poster']['href']) if 'genre' in jres: for g in jres['genre']: genres.append(g['$']) if 'runtime' in jres: nbsecs = jres['runtime'] duration = nbsecs / 60 if 'release' in jres: dstr = str(jres['release']['releaseDate']) tdate = dstr.split('-') day = 1 month = 1 year = 1901 if len(tdate) > 2: year = int(tdate[0]) month = int(tdate[1]) day = int(tdate[2]) release_date = datetime(year, month, day) if 'nationality' in jres: country = u'' for c in jres['nationality']: country += '%s, ' % c['$'] country = country.strip(', ') if 'synopsis' in jres: pitch = unicode(jres['synopsis']) if 'statistics' in jres and 'userRating' in jres['statistics']: note = u'%s/5 (%s votes)' % (jres['statistics']['userRating'], jres['statistics']['userReviewCount']) if 'castMember' in jres: for cast in jres['castMember']: if cast['activity']['$'] not in roles: roles[cast['activity']['$']] = [] person_to_append = (u'%s' % cast['person']['code'], cast['person']['name']) roles[cast['activity']['$']].append(person_to_append) movie = Movie(id, title) movie.other_titles = other_titles movie.release_date = release_date movie.duration = duration movie.genres = genres movie.pitch = pitch movie.country = country movie.note = note movie.roles = roles movie.short_description = short_description movie.all_release_dates = NotLoaded movie.thumbnail_url = thumbnail_url return movie def get_person(self, id): params = [('partner', self.PARTNER_KEY), ('code', id), ('profile', 'large'), ('mediafmt', 'mp4-lc'), ('filter', 'movie'), ('striptags', 'biography,biographyshort'), ('format', 'json')] jres = self.__do_request('person', params) if jres is not None: if 'person' in jres: jres = jres['person'] else: return None else: return None name = NotAvailable short_biography = NotAvailable biography = NotAvailable short_description = NotAvailable birth_place = NotAvailable birth_date = NotAvailable death_date = NotAvailable real_name = NotAvailable gender = NotAvailable thumbnail_url = NotAvailable roles = {} nationality = NotAvailable if 'name' in jres: name = u'' if 'given' in jres['name']: name += jres['name']['given'] if 'family' in jres['name']: name += ' %s' % jres['name']['family'] if 'biographyShort' in jres: short_biography = unicode(jres['biographyShort']) if 'birthPlace' in jres: birth_place = unicode(jres['birthPlace']) if 'birthDate' in jres: df = jres['birthDate'].split('-') birth_date = datetime(int(df[0]), int(df[1]), int(df[2])) if 'deathDate' in jres: df = jres['deathDate'].split('-') death_date = datetime(int(df[0]), int(df[1]), int(df[2])) if 'realName' in jres: real_name = unicode(jres['realName']) if 'gender' in jres: gcode = jres['gender'] if gcode == '1': gender = u'Male' else: gender = u'Female' if 'picture' in jres: thumbnail_url = unicode(jres['picture']['href']) if 'nationality' in jres: nationality = u'' for n in jres['nationality']: nationality += '%s, ' % n['$'] nationality = nationality.strip(', ') if 'biography' in jres: biography = unicode(jres['biography']) if 'participation' in jres: for m in jres['participation']: if m['activity']['$'] not in roles: roles[m['activity']['$']] = [] pyear = '????' if 'productionYear' in m['movie']: pyear = m['movie']['productionYear'] movie_to_append = (u'%s' % (m['movie']['code']), u'(%s) %s' % (pyear, m['movie']['originalTitle'])) roles[m['activity']['$']].append(movie_to_append) person = Person(id, name) person.real_name = real_name person.birth_date = birth_date person.death_date = death_date person.birth_place = birth_place person.gender = gender person.nationality = nationality person.short_biography = short_biography person.biography = biography person.short_description = short_description person.roles = roles person.thumbnail_url = thumbnail_url return person def iter_movie_persons(self, movie_id, role_filter): params = [('partner', self.PARTNER_KEY), ('code', movie_id), ('profile', 'large'), ('mediafmt', 'mp4-lc'), ('filter', 'movie'), ('striptags', 'synopsis,synopsisshort'), ('format', 'json')] jres = self.__do_request('movie', params) if jres is not None: if 'movie' in jres: jres = jres['movie'] else: return else: return if 'castMember' in jres: for cast in jres['castMember']: if (role_filter is None or (role_filter is not None and cast['activity']['$'].lower().strip() == role_filter.lower().strip())): id = cast['person']['code'] name = unicode(cast['person']['name']) short_description = unicode(cast['activity']['$']) if 'role' in cast: short_description += ', %s' % cast['role'] thumbnail_url = NotAvailable if 'picture' in cast: thumbnail_url = unicode(cast['picture']['href']) person = Person(id, name) person.short_description = short_description person.real_name = NotLoaded person.birth_place = NotLoaded person.birth_date = NotLoaded person.death_date = NotLoaded person.gender = NotLoaded person.nationality = NotLoaded person.short_biography = NotLoaded person.roles = NotLoaded person.thumbnail_url = thumbnail_url yield person def iter_person_movies(self, person_id, role_filter): params = [('partner', self.PARTNER_KEY), ('code', person_id), ('profile', 'medium'), ('filter', 'movie'), ('format', 'json')] jres = self.__do_request('filmography', params) if jres is not None: if 'person' in jres: jres = jres['person'] else: return else: return for m in jres['participation']: if (role_filter is None or (role_filter is not None and m['activity']['$'].lower().strip() == role_filter.lower().strip())): prod_year = '????' if 'productionYear' in m['movie']: prod_year = m['movie']['productionYear'] short_description = u'(%s) %s' % (prod_year, m['activity']['$']) if 'role' in m: short_description += ', %s' % m['role'] movie = Movie(m['movie']['code'], unicode(m['movie']['originalTitle'])) movie.other_titles = NotLoaded movie.release_date = NotLoaded movie.duration = NotLoaded movie.short_description = short_description movie.pitch = NotLoaded movie.country = NotLoaded movie.note = NotLoaded movie.roles = NotLoaded movie.all_release_dates = NotLoaded movie.thumbnail_url = NotLoaded yield movie def iter_person_movies_ids(self, person_id): params = [('partner', self.PARTNER_KEY), ('code', person_id), ('profile', 'medium'), ('filter', 'movie'), ('format', 'json')] jres = self.__do_request('filmography', params) if jres is not None: if 'person' in jres: jres = jres['person'] else: return else: return for m in jres['participation']: yield unicode(m['movie']['code']) def iter_movie_persons_ids(self, movie_id): params = [('partner', self.PARTNER_KEY), ('code', movie_id), ('profile', 'large'), ('mediafmt', 'mp4-lc'), ('filter', 'movie'), ('striptags', 'synopsis,synopsisshort'), ('format', 'json')] jres = self.__do_request('movie', params) if jres is not None: if 'movie' in jres: jres = jres['movie'] else: return else: return if 'castMember' in jres: for cast in jres['castMember']: yield unicode(cast['person']['code']) def get_movie_releases(self, id, country): if country == 'fr': return self.get_movie(id).release_date def get_person_biography(self, id): params = [('partner', self.PARTNER_KEY), ('code', id), ('profile', 'large'), ('mediafmt', 'mp4-lc'), ('filter', 'movie'), ('striptags', 'biography,biographyshort'), ('format', 'json')] jres = self.__do_request('person', params) if jres is not None: if 'person' in jres: jres = jres['person'] else: return None else: return None biography = NotAvailable if 'biography' in jres: biography = unicode(jres['biography']) return biography def get_categories_movies(self, category): params = [('partner', self.PARTNER_KEY), ('format', 'json'), ('mediafmt', 'mp4'), ('filter', category)] result = self.__do_request('movielist', params) if result is None: return for movie in result['feed']['movie']: if 'trailer' not in movie or 'productionYear' not in movie: continue yield self.parse_movie(movie) def get_categories_videos(self, category): params = [('partner', self.PARTNER_KEY), ('format', 'json'), ('mediafmt', 'mp4'), ('filter', category)] result = self.__do_request('videolist', params) if result is None: return if 'feed' in result and 'media' in result['feed']: for episode in result['feed']['media']: if 'title' in episode: yield self.parse_video(episode, category) def parse_video(self, _video, category): video = BaseVideo(u'%s#%s' % (_video['code'], category)) video.title = unicode(_video['title']) video._video_code = unicode(_video['code']) video.ext = u'mp4' if 'runtime' in _video: video.duration = timedelta(seconds=int(_video['runtime'])) if 'description' in _video: video.description = unicode(_video['description']) renditions = sorted( _video['rendition'], key=lambda x: 'bandwidth' in x and x['bandwidth']['code'], reverse=True) video.url = unicode( max(renditions, key=lambda x: 'bandwidth' in x)['href']) return video def parse_movie(self, movie): video = BaseVideo(u'%s#%s' % (movie['code'], 'movie')) video.title = unicode(movie['trailer']['name']) video._video_code = unicode(movie['trailer']['code']) video.ext = u'mp4' if 'poster' in movie: video.thumbnail = Thumbnail(movie['poster']['href']) video.thumbnail.url = unicode(movie['poster']['href']) tdate = movie['release']['releaseDate'].split('-') day = 1 month = 1 year = 1901 if len(tdate) > 2: year = int(tdate[0]) month = int(tdate[1]) day = int(tdate[2]) video.date = date(year, month, day) if 'userRating' in movie['statistics']: video.rating = movie['statistics']['userRating'] elif 'pressRating' in movie['statistics']: video.rating = movie['statistics']['pressRating'] * 2 video.rating_max = 5 if 'synopsis' in movie: video.description = unicode(movie['synopsis'].replace( '<p>', '').replace('</p>', '')) elif 'synopsisShort' in movie: video.description = unicode(movie['synopsisShort'].replace( '<p>', '').replace('</p>', '')) if 'castingShort' in movie: if 'directors' in movie['castingShort']: video.author = unicode(movie['castingShort']['directors']) if 'runtime' in movie: video.duration = timedelta(seconds=int(movie['runtime'])) return video def get_movie_from_id(self, _id): params = [ ('partner', self.PARTNER_KEY), ('format', 'json'), ('mediafmt', 'mp4'), ('filter', 'movie'), ('code', _id), ] result = self.__do_request('movie', params) if result is None: return return self.parse_movie(result['movie']) def get_video_from_id(self, _id, category): return find_object(self.get_categories_videos(category), id=u'%s#%s' % (_id, category)) def get_video_url(self, code): params = [ ('partner', self.PARTNER_KEY), ('format', 'json'), ('mediafmt', 'mp4'), ('code', code), ('profile', 'large'), ] result = self.__do_request('media', params) if result is None: return renditions = sorted( result['media']['rendition'], key=lambda x: 'bandwidth' in x and x['bandwidth']['code'], reverse=True) return max(renditions, key=lambda x: 'bandwidth' in x)['href'] def get_emissions(self, basename): params = [ ('partner', self.PARTNER_KEY), ('format', 'json'), ('filter', 'acshow'), ] result = self.__do_request('termlist', params) if result is None: return for emission in result['feed']['term']: yield Collection( [basename, unicode(emission['nameShort'])], unicode(emission['$'])) def search_events(self, query): params = [('partner', self.PARTNER_KEY), ('format', 'json'), ('zip', query.city)] if query.summary: movie = next(self.iter_movies(query.summary)) params.append(('movie', movie.id)) result = self.__do_request('showtimelist', params) if result is None: return for event in self.create_event(result): if (not query.end_date or event.start_date <= query.end_date)\ and event.start_date >= query.start_date: yield event def get_event(self, _id): split_id = _id.split('#') params = [ ('partner', self.PARTNER_KEY), ('format', 'json'), ('theaters', split_id[0]), ('zip', split_id[1]), ('movie', split_id[2]), ] result = self.__do_request('showtimelist', params) if result is None: return for event in self.create_event(result): if event.id.split('#')[-1] == split_id[-1]: event.description = self.get_movie(split_id[2]).pitch return event def create_event(self, data): sequence = 1 transp = TRANSP.TRANSPARENT status = STATUS.CONFIRMED category = CATEGORIES.CINE if 'theaterShowtimes' not in data['feed']: return for items in data['feed']['theaterShowtimes']: cinema = items['place']['theater'] city = unicode(cinema['city']) location = u'%s, %s' % (cinema['name'], cinema['address']) postalCode = cinema['postalCode'] cinemaCode = cinema['code'] for show in items['movieShowtimes']: summary = unicode(show['onShow']['movie']['title']) movieCode = show['onShow']['movie']['code'] for jour in show['scr']: tdate = jour['d'].split('-') year = int(tdate[0]) month = int(tdate[1]) day = int(tdate[2]) for seance in jour['t']: ttime = seance['$'].split(':') heure = int(ttime[0]) minute = int(ttime[1]) start_date = datetime(year=year, month=month, day=day, hour=heure, minute=minute) seanceCode = seance['code'] _id = u'%s#%s#%s#%s' % (cinemaCode, postalCode, movieCode, seanceCode) event = BaseCalendarEvent() event.id = _id event.sequence = sequence event.transp = transp event.status = status event.category = category event.city = city event.location = location event.start_date = start_date event.summary = summary event.timezone = u'Europe/Paris' yield event
class S2eBrowser(LoginBrowser): PROFILE = Android() CTCC = "" LANG = "FR" sessionId = None loginp = URL('/$', LoginPage) calcp = URL( '/s2e_services/restServices/calculetteService/grillemdp\?uuid=(?P<uuid>)', CalcPage) profilp = URL('/s2e_services/restServices/authentification/loginS', ProfilPage) accountsp = URL('/s2e_services/restServices/situationCompte', AccountsPage) historyp = URL('/s2e_services/restServices/listeOperation', HistoryPage) i18np = URL('/(?P<lang1>.*)/LANG/(?P<lang2>.*).json', I18nPage) def __init__(self, url, username, password, *args, **kwargs): super(S2eBrowser, self).__init__(username, password, *args, **kwargs) self.BASEURL = "https://" + url def do_login(self): self.logger.debug('call Browser.do_login') self.loginp.stay_or_go() self.sessionId = self.page.login(self.username, self.password) if self.sessionId is None: raise BrowserIncorrectPassword() @need_login def get_accounts_list(self): data = { 'clang': self.LANG, 'ctcc': self.CTCC, 'login': self.username, 'session': self.sessionId } for dispositif in self.accountsp.go(data=data).get_list(): if dispositif['montantBrutDispositif'] == 0: continue a = Account() a.id = dispositif['codeDispositif'] a.type = Account.TYPE_MARKET a.balance = Decimal(dispositif["montantBrutDispositif"]).quantize( Decimal('.01')) a.label = dispositif['titreDispositif'] a.currency = u"EUR" # Don't find any possbility to get that from configuration. a._investments = [] for fund in dispositif['listeFonds']: if fund['montantValeurEuro'] == 0: continue i = Investment() i.id = i.code = dispositif['codeEntreprise'] + dispositif[ "codeDispositif"] + fund["codeSupport"] i.label = fund['libelleSupport'] i.unitvalue = Decimal(fund["montantValeur"]).quantize( Decimal('.01')) i.valuation = Decimal(fund["montantValeurEuro"]).quantize( Decimal('.01')) i.quantity = i.valuation / i.unitvalue i.vdate = parse_date(fund['dateValeur'], dayfirst=True) a._investments.append(i) yield a @need_login def iter_history(self, account): # Load i18n for type translation self.i18np.go(lang1=self.LANG, lang2=self.LANG).load_i18n() # For now detail for each account is not available. History is global for all accounts and very simplist data = { 'clang': self.LANG, 'ctcc': self.CTCC, 'login': self.username, 'session': self.sessionId } for trans in self.historyp.go(data=data).get_transactions(): t = Transaction() t.date = datetime.strptime(trans["dateHeureSaisie"], "%d/%m/%Y") t.rdate = datetime.strptime(trans["dateHeureSaisie"], "%d/%m/%Y") t.type = Transaction.TYPE_DEPOSIT if trans[ "montantNetEuro"] > 0 else Transaction.TYPE_PAYBACK t.raw = trans["typeOperation"] try: t.label = self.i18n["OPERATION_TYPE_" + trans["casDeGestion"]] except KeyError: t.label = self.i18n["OPERATION_TYPE_TOTAL_" + trans["casDeGestion"]] t.amount = Decimal(trans["montantNetEuro"]).quantize( Decimal('.01')) yield t