def save(enriched): for record in enriched: address, price, url, noisy, commute, catchment_gids, point = record realestate = RealEstate(address=address, price=price, url=url, commute=commute, noisy=noisy, geom=WKTElement(point, srid=4326)) cs = session.query(Catchments).filter( Catchments.gid.in_(catchment_gids)).all() # better way to do this? for c in cs: a = Association() a.catchments = c realestate.catchments.append(a) session.add(realestate) try: session.commit() logger.info(f'Successfully commited records to database.') return True except Exception as err: logging.error(f'Error saving record: {err}') return False
def map(self, payment): # Traemos la factura que este pago cancela el pago (payment) invoice = Invoice.all().filter('Trx_id', payment.trx_id).get() if not invoice: logging.error('No encontre factura para el pago %s' % str(payment.key())) return ([], []) # Obtenemos el realestate en funcion del trx_id id_or_name = payment.trx_id[7:] #YYYYMM[NI]ddddddd re = None if payment.trx_id[6] == 'I': re = RealEstate.get_by_id(int(id_or_name)) else: re = RealEstate.get_by_key_name(id_or_name) if re is None: logging.error('No encontre el realestate para %s' % payment.trx_id) return ([], []) invoice.realestate = re # Ponemos la factura en estado pagada invoice.state = Invoice._PAID invoice.payment = payment invoice.save() # Acabamos de asignar un pago, deberiamos automaticamente # poner en ENABLED a la inmo si es que no estaba en ese estado # Si esta volviendo a ENABLE desde NO_PAYMENT debemos comunicarle que 'las props estan publicadas nuevamente' oldst = re.status # payment_received if re.status == RealEstate._ENABLED: send_mail('payment_received', re) else: re.status = RealEstate._ENABLED re.save() if oldst == RealEstate._NO_PAYMENT: send_mail('enabled_again', re, invoice) payment.assigned = 1 return ([payment], []) # update/delete
def by_slug(self, **kwargs): self.realestate = RealEstate.all().filter(' domain_id = ', kwargs.get('realestate_slug')).get() # Ponemos la pantalla de disabled si esta en NO_PAYMENT if self.realestate.status == RealEstate._NO_PAYMENT or self.realestate.plan.allow_website == 0: return self.render_response('realestate/disabled.html', realestate=self.realestate) return self.get2(**kwargs)
def get(self, **kwargs): kwargs['mnutop'] = 'realestatebook' realestate = get_or_404(self.get_realestate_key()) if not self.plan_allow_realestatefriendship: self.set_warning( u'Su plan no tiene acceso al servicio de la red de inmobiliarias de ULTRAPROP que le permite ampliar su oferta y compartirla con sus colegas. Comuníquese con Ultraprop si desea utilizarlo.' ) return self.redirect_to('property/list') keys = [realestate.key()] friends = RealEstateFriendship.all(keys_only=True).filter( 'realestates = ', str(realestate.key())).filter( 'state = ', RealEstateFriendship._ACCEPTED).fetch(1000) requesteds = RealEstateFriendship.all(keys_only=True).filter( 'realestates = ', str(realestate.key())).fetch(1000) realestate_str_key = str(realestate.key()) query = RealEstate.all().filter('__key__ != ', realestate.key()) if not self.has_role('ultraadmin'): query.filter(' is_tester = ', False) already_friends = [] if friends: for request in friends: current_key = RealEstateFriendship.get_the_other( request, realestate_str_key, get_key=False) already_friends.append(current_key) denied = [] friend_req_sent = [] if requesteds: for request in requesteds: current_key = RealEstateFriendship.get_the_other( request, realestate_str_key, get_key=False) if current_key not in already_friends: if RealEstateFriendship.is_sender_ex( request, realestate_str_key): friend_req_sent.append(current_key) else: if db.get( request).state == RealEstateFriendship._DENIED: denied.append(current_key) else: friend_req_sent.append(current_key) kwargs['denied'] = denied kwargs['already_friends'] = already_friends kwargs['friend_req_sent'] = friend_req_sent kwargs['realestates'] = query.fetch(1000) return self.render_response('backend/realestatebook_search.html', **kwargs)
def getto(self, realestate, **kwargs): # Ponemos la pantalla de disabled si esta en NO_PAYMENT if realestate.status == RealEstate._NO_PAYMENT or realestate.plan.allow_website == 0: return self.render_response('realestate/disabled.html', realestate=realestate) kwargs['realestate'] = realestate kwargs['menu_item'] = 'index' kwargs['form'] = self.form kwargs['properties'] = Property.all().filter( ' location_geocells = ', RealEstate.get_realestate_sharing_key( None, realestate=realestate)).filter( ' status = ', Property._PUBLISHED).fetch( get_props_at_home(realestate.get_web_theme())) return self.render_response('realestate/index.html', **kwargs)
def __init__(self, owner, friend, do_add=True, for_admin=True, for_website=False): self.owner = owner self.friend = friend self.friend_website = RealEstate.get_realestate_sharing_key(friend) self.do_add = do_add self.for_admin = for_admin self.for_website = for_website self.FILTERS = [('realestate', db.Key(owner))] # logging.error(u'NetworkPropertyMapper::__init__() owner:%s friend:%s'%(self.owner, self.friend)); super(NetworkPropertyMapper, self).__init__() return
def validate_domain_id(domain_id, mykey=None): if domain_id.strip() == '': return {'result': 'used', 'msg': u'El nombre no puede ser vacío'} if domain_id.strip() in ['mapa', 'admin', 'red-ultraprop', '']: return {'result': 'used', 'msg': u'Este nombre está restringido'} # Primero validamos que sea tipo regex SLUG_REGEX = re.compile('^[-\w]+$') if not re.match(SLUG_REGEX, domain_id): return { 'result': 'noslug', 'msg': 'El nombre solo puede contener letras, numeros y guiones' } tmp = RealEstate.all(keys_only=True).filter('domain_id', domain_id).get() if tmp and (mykey is None or str(tmp) != mykey): return {'result': 'used', 'msg': 'El nombre ya esta siendo utilizado'} return {'result': 'free', 'msg': 'El nombre se encuentra disponible'}
def validate_name(form, field): # Chequeo que el nombre de la inmo no este repetido name = RealEstate.all().filter('name', field.data.strip()).get() if name: raise ValidationError(u'Ese nombre ya esta siendo utilizado.')
def post(self, **kwargs): self.request.charset = 'utf-8' plan = get_or_404(self.request.POST['plan']) form_validated = self.form.validate() if not form_validated: kwargs['form'] = self.form if self.form.errors: kwargs['flash'] = self.build_error( 'Verifique los datos ingresados:<br/> ' + '<br/> '.join( reduce(lambda x, y: '' + str(x) + ' ' + str(y), t) for t in self.form.errors.values())) kwargs['plan'] = plan return self.render_response('backend/signup.html', **kwargs) # Generamos la inmo en estado TRIAL y le ponemos el Plan realEstate = RealEstate.new() #realEstate.telephone_number = self.form.telephone_number.data realEstate.name = self.form.email.data.split('@')[0] realEstate.email = self.form.email.data realEstate.plan = plan realEstate.status = RealEstate._ENABLED if plan.is_free else RealEstate._REGISTERED realEstate.email_image = None realEstate.email_image_url = '' realEstate.put() # Generamos la primer factura con fecha hoy+dias_gratis # Utilizamos el indicador I para indicar 'id' en vez de 'name' first_date = (datetime.utcnow() + timedelta(days=plan.free_days)).date() if first_date.day > 28: first_date = date(first_date.year, first_date.month, 28) invoice = Invoice() invoice.realestate = realEstate invoice.trx_id = '%sI%d' % (first_date.strftime('%Y%m'), realEstate.key().id()) invoice.amount = plan.amount invoice.state = Invoice._NOT_PAID if not plan.is_free else Invoice._INBANK invoice.date = first_date invoice.put() # Volvemos a guardar el realEstate con los datos nuevos realEstate.last_invoice = invoice.date realEstate.save() # Generamos el usuario y le asignamos la realestate user = User.new() user.email = self.form.email.data user.password = self.form.password.data user.rol = 'owner' user.realestate = realEstate user.put() # Mando Correo de bienvenida y validación de eMail. # Armo el contexto dado que lo utilizo para mail plano y mail HTML. context = { 'server_url': 'http://' + self.request.headers.get('host', 'no host'), 'realestate_name': realEstate.name, 'validate_user_link': self.url_for('backend/validate/user', key=str(user.key()), _full=True), 'support_url': 'http://' + self.request.headers.get('host', 'no host') } # Armo el body en plain text. body = self.render_template( 'email/' + self.config['directodueno']['mail']['signup']['template'] + '.txt', **context) # Armo el body en HTML. html = self.render_template( 'email/' + self.config['directodueno']['mail']['signup']['template'] + '.html', **context) # Envío el correo. mail.send_mail(sender="www.directodueno.com <%s>" % self.config['directodueno']['mail']['signup']['sender'], to=user.email, subject=u'Bienvenido a DirectoDueño!', body=body, html=html) self.set_ok( u'Un correo ha sido enviado a su casilla de email. Ingrese a DirectoDueño a través del enlace recibido.' ) return self.redirect_to('backend/auth/login')
import csv import sys from google.appengine.ext import db from models import Property, PropertyIndex, RealEstate from search_helper import config_array, alphabet, calculate_price fout = open('realstatebulked.csv', "w") csvout = csv.writer(fout, delimiter=',', quotechar='"', lineterminator='\n') # Atributos del objeto Propiedad para imprimir en el csv del bulker. attribute_headers = [u'key'] # Itero sobre el metodo 'public_attributes()' de propiedad para obtener los atributos del objeto y generar el csv del bulker. # Este metodo tambien es utilizado por la librería del 'service/search', pra generar el Json. for key in RealEstate.public_attributes(): attribute_headers.append(u'%s' % unicode(key)) # Agrego atributo realestate (que no es retornado por el método 'public_attributes()') y el string location el cual agrego a mano para generar el csv. #attribute_headers.append(u'realestate') #attribute_headers.append(u'location') # Escribo el header de los atributos a bulkear en el csv. csvout.writerow(map(lambda x: x.encode('utf8'), attribute_headers)) # Arreglo que contiene los tipos de currency. currencies = {'US': 'USD', 'PE': 'ARS', '': ''} csvreader = csv.reader(open('normalized_inm.csv', 'r'), delimiter=',', quotechar='"')
def add_extra_filter(self, base_query): base_query.filter('status =', Property._PUBLISHED) # base_query.filter('realestate =', self.realestate ) base_query.filter('location_geocells =', RealEstate.get_realestate_sharing_key(None, self.realestate))
def get(self, **kwargs): realestates = RealEstate.all().order('name') return self.render_response('frontend/red.html', realestates=realestates, status_disabled=RealEstate._NO_PAYMENT)
def by_slug(self, **kwargs): self.realestate = RealEstate.all().filter( ' domain_id = ', kwargs.get('realestate_slug')).get() if not self.realestate: abort(404) return self.getto(realestate=self.realestate, **kwargs)
def get(self, **kwargs): realestates = RealEstate.all().order('name') return self.render_response('frontend/red.html' , realestates = realestates)
def post(self, **kwargs): self.request.charset = 'utf-8' kwargs['planes'] = Plan.all().filter('online = ', 1).filter( 'enabled = ', 1).order('amount').fetch(3) kwargs['selected_plan'] = None plan = get_or_404(self.request.POST.get('plan')) # if not plan: # kwargs['form'] = self.form # kwargs['flash'] = self.build_error('Seleccione un plan vigente.') # return self.render_response('backend/signup.html', **kwargs) form_validated = self.form.validate() if not form_validated: kwargs['form'] = self.form if self.form.errors: kwargs['flash'] = self.build_error( 'Verifique los datos ingresados.') kwargs['default_plan'] = str(plan.key()) return self.render_response('backend/signup.html', **kwargs) # Generamos la inmo en estado TRIAL y le ponemos el Plan realEstate = RealEstate.new() realEstate.telephone_number = self.form.telephone_number.data realEstate.name = self.form.name.data realEstate.email = self.form.email.data realEstate.plan = plan # realEstate.status = RealEstate._REGISTERED realEstate.status = RealEstate._ENABLED if plan.is_free else RealEstate._REGISTERED realEstate.email_image = None realEstate.email_image_url = '' # Ya tenemos registrado ese domain_id realEstate.domain_id = do_slugify(realEstate.name) tmp = validate_domain_id(realEstate.domain_id) if tmp['result'] != 'free': realEstate.domain_id = realEstate.domain_id + datetime.now( ).strftime('%Y%m%d%H%M') realEstate.put() # Generamos la primer factura con fecha hoy+dias_gratis # Utilizamos el indicador I para indicar 'id' en vez de 'name' first_date = (datetime.utcnow() + timedelta(days=plan.free_days)).date() if first_date.day > 28: first_date = date(first_date.year, first_date.month, 28) invoice = Invoice() invoice.realestate = realEstate invoice.trx_id = '%sI%d' % (first_date.strftime('%Y%m'), realEstate.key().id()) invoice.amount = plan.amount #invoice.state = Invoice._NOT_PAID if plan.amount > 0 else Invoice._INBANK invoice.state = Invoice._NOT_PAID if not plan.is_free else Invoice._INBANK invoice.date = first_date invoice.put() # Volvemos a guardar el realEstate con los datos nuevos realEstate.last_invoice = invoice.date realEstate.save() # Generamos el usuario y le asignamos la realestate user = User.new() user.email = self.form.email.data user.password = self.form.password.data user.rol = 'owner' user.realestate = realEstate user.put() # Mando Correo de bienvenida y validación de eMail. # Armo el contexto dado que lo utilizo para mail plano y mail HTML. context = { 'server_url': 'http://' + self.request.headers.get('host', 'no host'), 'realestate_name': realEstate.name, 'validate_user_link': self.url_for('backend/validate/user', key=str(user.key()), _full=True), 'support_url': 'http://' + self.request.headers.get('host', 'no host') } # Armo el body en plain text. body = self.render_template( 'email/' + self.config['ultraprop']['mail']['signup']['template'] + '.txt', **context) # Armo el body en HTML. html = self.render_template( 'email/' + self.config['ultraprop']['mail']['signup']['template'] + '.html', **context) # Envío el correo. mail.send_mail(sender="www.ultraprop.com.ar <%s>" % self.config['ultraprop']['mail']['signup']['sender'], to=user.email, subject="ULTRAPROP - Bienvenido", body=body, html=html) self.set_ok( u'Un correo ha sido enviado a su casilla de email. Ingrese a ULTRAPROP a través del enlace recibido.' ) return self.redirect_to('backend/auth/login')
def import_real_estate_data(src_file_s3_bucket, src_filename, file_date_key, file_time_key, flush_every=1000, session=None): """Function to import the raw json file from S3 into database. :param src_file_s3_bucket: Source file S3 bucket name :type src_file_s3_bucket: str :param src_filename: Source file name :type src_filename: str :param file_date_key: File date key :param file_date_key: integer :param file_time_key: File time key in 'HH:MM:SS' format :type file_time_key: str :param flush_every: Flush data to table after number of rows :type flush_every: integer :param session: Session object for connecting to database :type session: SQL Alchemy session object """ row_count = 0 bad_row_count = 0 print( 'Deleting rows from table {0} for file date key {1} and time key {2}'. format(RealEstate.__tablename__, file_date_key, file_time_key)) session.query(RealEstate).filter( RealEstate.file_date_key == file_date_key and RealEstate.file_time_key == file_time_key).delete( synchronize_session=False) session.commit() print('Reading file {0} from S3 bucket {1}'.format(src_filename, src_file_s3_bucket)) result = boto3.client("s3").get_object(Bucket=src_file_s3_bucket, Key=src_filename) for i, line in enumerate(result["Body"].iter_lines()): json_data = json.loads(line.decode('utf-8')) if json_data['ok']: stage_data = RealEstate(file_date_key=file_date_key, file_time_key=file_time_key, data=json_data['data']) session.add(stage_data) row_count = row_count + 1 if row_count % flush_every == 0: session.flush() print('Inserted total {0} rows in table {1}'.format( row_count, RealEstate.__tablename__)) else: bad_row_count = bad_row_count + 1 session.commit() print('Inserted total {0} rows in table {1}'.format( row_count, RealEstate.__tablename__)) print('Skipped importing bad rows count {}'.format(bad_row_count)) print('Finished importing data to table {}'.format( RealEstate.__tablename__))