def post(self): # Check if they gave a token if self.request.get('token'): # They did so now let's check the client client_obj = authenticate_client(str(self.request.get('token'))) # Check client if client_obj and client_obj is not False: # Well get the details # http://www.identichip.org/apis/v1/contact?token=testing&key=ag5kZXZ-aWRlbnRpY2hpcHIQCxIKVXNlclNlYXJjaBhwDA&option=ag5kZXZ-aWRlbnRpY2hpcHIWCxIQVXNlclNlYXJjaERldGFpbBhxDA if self.request.get('key'): # Get the search object and responses (search_obj, search_responses) = dal.search_by_token(self.request.get('key')) # Check if the search exists and if any responses are associated with it. if search_obj and search_responses and search_obj.expires > datetime.datetime.now(): # Filter the Results to what we need success_results = [] failure_results = [] for response in search_responses: if response.status == runner.ProviderResponse.STATUS_FOUND: success_results.append(response) elif response.status not in [runner.ProviderResponse.STATUS_FOUND, runner.ProviderResponse.STATUS_NOTFOUND]: failure_results.append(response) # Get the current provider, chip and owner to show if len(success_results) > 0: # What response should we look at ? current_index = 0 if self.request.get('provider'): # Only executed if the user provided a provider to check for. # This is used when multiple provider gave a response. # So we can list all the responses for the user. try: # Get the index of a the provider with that id current_index = [y.provider.key() for y in success_results].index(str(self.request.get('provider'))) except Exception as ex: # Just use the default value current_index = 0 # Check that the index is sane else we make it the first one if current_index > (len(success_results)): current_index = 0 # Single Response Object single_response = success_results[current_index] # Get the provider provider = success_results[current_index].provider # Get the Chip Details chip = json.loads(success_results[current_index].parsed_response) # Handle the contact form contact_name = self.request.POST.get('contact_name') contact_email = self.request.POST.get('contact_email') contact_message = self.request.POST.get('contact_message') if single_response.email_sent == True: # We can't send multiple E-Mails to the same user on the same search self.response.out.write(json.dumps({ 'error': 'An E-Mail has already been sent to the user. We do not allow multiple E-Mails to prevent spamming. Please give the user some time to response to your E-Mail after which you\'ll be able to communicate directly.' })) elif not contact_name or len(str(contact_name).strip()) == 0: # Name is Required self.response.out.write(json.dumps({ 'error': 'The Name of the person that wants to send the Mail is required' })) elif not contact_email or len(str(contact_email).strip()) == 0 or not re.match(r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$", contact_email): # An Valid E-Mail is Required self.response.out.write(json.dumps({ 'error': 'The Valid E-Mail of the user is required. This must match our pattern!' })) elif not contact_message or len(str(contact_message).strip()) == 0: # Message is required self.response.out.write(json.dumps({ 'error': 'We need a message which we will send to the user. This should include basic details such as where the user found the pet and their location or some arrange to call them.' })) else: # Generate Template to send template_locales = { 'chip': chip, 'subject': 'Contact message by User who searched for #' + str(chip.uid), 'sender_name': str(contact_name).strip(), 'sender_email': str(contact_email).strip(), 'message': str(contact_message).strip(), 'provider': provider } # The Form parameters were validated mailer.send( to=str(chip['owner']['email']), reply_to=str(template_locales['sender_email']), subject=str(template_locales['subject']), view='mail/contact_from_search.html', locales=template_locales) # Update to show that the E-Mail was sent single_response.email_sent = True single_response.email_sent_from = str(contact_email).strip() single_response.email_sent_name = str(contact_name).strip() single_response.email_sent_text = str(contact_message).strip() single_response.put() self.response.out.write(json.dumps({ 'message': 'Success E-Mail was sent !', 'status': True })) else: # This was not a succesfull search ! self.response.out.write(json.dumps({ 'error': 'This was not a succesfull search.' })) else: # Search not found or expired self.response.out.write(json.dumps({ 'error': 'Either your search could not be found or it has expired. Searches are only valid for ' + str(runner.EXPIRES_AFTER) + ' minutes after their last action' })) else: # self.response.out.write(json.dumps({ 'error': 'No Search Key Provided' })) else: # Inform them self.response.out.write(json.dumps({ 'error': 'No such client found. Invalid Token !' })) else: # Inform them self.response.out.write(json.dumps({ 'error': 'No Client token was given. Please login and create a client to start searching from our providers' }))
def get(self, uid, result_number=0): if uid: # Get the search object and responses (search_obj, search_responses) = dal.search_by_token(uid) # Check if the search exists and if any responses are associated with it. if search_obj and search_responses and search_obj.expires > datetime.datetime.now(): # Get the current logged-in user user = users.get_current_user() # Update the expiring date. We allow anyone to view the search x minutes after it's been searched search_obj.expires = datetime.datetime.now() + datetime.timedelta( minutes=runner.EXPIRES_AFTER ) search_obj.put() # Filter the Results to what we need success_results = [] failure_results = [] for response in search_responses: if response.status == runner.ProviderResponse.STATUS_FOUND: success_results.append(response) elif response.status not in [runner.ProviderResponse.STATUS_FOUND, runner.ProviderResponse.STATUS_NOTFOUND]: failure_results.append(response) # Get the current provider, chip and owner to show if len(success_results) > 0: # What response should we look at ? current_index = 0 if self.request.get('provider'): # Only executed if the user provided a provider to check for. # This is used when multiple provider gave a response. # So we can list all the responses for the user. try: # Assign custom index from request requested_provider_uid = int(self.request.get('provider')) # Get the index of a the provider with that id current_index = [int(y.provider.key().id()) for y in success_results].index(requested_provider_uid) except Exception as ex: # Just use the default value current_index = 0 # Check that the index is sane else we make it the first one if current_index > (len(success_results)): current_index = 0 # Single Response Object single_response = success_results[current_index] # Get the provider provider = success_results[current_index].provider # Get the Chip Details chip = json.loads(success_results[current_index].parsed_response) # Section of the Result Page to show. section = 'info' # Set section according to request if self.request.get('section'): # Parse the string as a section requested_section_str = str(self.request.get('section').strip().lower()) # Is this a valid Section if requested_section_str in ['info', 'result', 'contact']: # Then we assign it section = requested_section_str # ######## # Handle Posts if any # ######## # success_message_flags contact_form_success = False # Errors contact_form_error = False # Handle Contact Form if self.request.POST.get('form_contact'): # Set section as they will want to see their response section = 'contact' # Handle the contact form contact_name = self.request.POST.get('form_contact_name') contact_email = self.request.POST.get('form_contact_email') contact_message = self.request.POST.get('form_contact_message') # Validate contact_form_error = None if single_response.email_sent == True: # We can't send multiple E-Mails to the same user on the same search contact_form_error = 'An E-Mail has already been sent to the user. We do not allow multiple E-Mails to prevent spamming. Please give the user some time to response to your E-Mail after which you\'ll be able to communicate directly.' elif not contact_name or len(str(contact_name).strip()) == 0: # Name is Required contact_form_error = 'Your name is Required' elif not contact_email or len(str(contact_email).strip()) == 0 or not re.match(r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$", contact_email): # An Valid E-Mail is Required contact_form_error = 'A Valid E-Mail by which the user can reach you again.' elif not contact_message or len(str(contact_message).strip()) == 0: # Message is required contact_form_error = 'We need a message which we will send to the user. This should include basic details such as where you found the pet and your location' else: # Generate Template to send template_locales = { 'title': 'Search for #' + str(search_obj.uid), 'description': 'Contact message by User who searched for #' + str(search_obj.uid), 'chip': chip, 'subject': 'Contact message by User who searched for #' + str(search_obj.uid), 'sender_name': str(contact_name).strip(), 'sender_email': str(contact_email).strip(), 'message': str(contact_message).strip(), 'provider': provider } # The Form parameters were validated mailer.send( to=str(chip['owner']['email']), reply_to=str(template_locales['sender_email']), subject=str(template_locales['subject']), view='mail/contact_from_search.html', locales=template_locales) # Update to show that the E-Mail was sent single_response.email_sent = True single_response.email_sent_from = str(contact_email).strip() single_response.email_sent_name = str(contact_name).strip() single_response.email_sent_text = str(contact_message).strip() single_response.put() section = 'info' contact_form_success = 'true' # Create the Locales for the Page to use locales = { 'title': 'Search for #' + str(search_obj.uid), 'description': 'The results of the search for the Unique Number #' + str(search_obj.uid), 'chip': chip, 'current_response': single_response, 'search': search_obj, 'provider': provider, 'success_results': search_obj.provider_success_responses, 'failure_results': search_obj.provider_failure_responses, 'notfound_results': search_obj.provider_notfound_responses, 'total_providers_asked': search_obj.provider_total_requests, 'search_obj': search_obj, 'search_responses': search_responses, 'search_success_responses': success_results, 'search_failure_responses': failure_results, 'user': user, 'contact_form_error': contact_form_error, 'contact_form_success': contact_form_success, 'section': section, 'post_params': self.request.POST, 'contact_post_url': '/view/' + search_obj.token + "?provider=" + str(provider.key().id()) + "&response=" + str(single_response.key().id()), 'session': dal.return_and_global_session_update(self), 'is_current_user_admin': users.is_current_user_admin() } # Render the Template with those Values template = jinja_environment.get_template('search/result.html') self.response.out.write(template.render(locales)) else: session_store = sessions.get_store(request=self.request) session = session_store.get_session() if 'search_token' not in session: session['search_token'] = str(uuid.uuid1()) session_store.save_sessions(self.response) # Well if their was not result we redirect to homepage # Create the Locales for the Page to use locales = { 'title': 'No Results found for #' + str(search_obj.uid), 'description': 'The results of the search for the Unique Number #' + str(search_obj.uid), 'success_results': search_obj.provider_success_responses, 'failure_results': search_obj.provider_failure_responses, 'notfound_results': search_obj.provider_notfound_responses, 'total_providers_asked': search_obj.provider_total_requests, 'search_obj': search_obj, 'search': search_obj, 'search_responses': search_responses, 'search_success_responses': success_results, 'search_failure_responses': failure_results, 'user': user, 'session': session, 'session': dal.return_and_global_session_update(self), 'is_current_user_admin': users.is_current_user_admin() } # self.response.out.write("<li>" + detail.provider.name + " <-> <img src=\"" + images.get_serving_url(detail.provider.logo.key(), 32) + "\" /></li>") # Render the Template with those Values template = jinja_environment.get_template('search/notfound.html') self.response.out.write(template.render(locales)) else: # That search does not exist. Redirect them to the homepage. self.redirect('/') else: # They did not give a search uid redirect them to the homepage self.redirect('/')
def post(self): # Check if they gave a token if self.request.get('token'): # They did so now let's check the client client_obj = authenticate_client(str(self.request.get('token'))) # Check client if client_obj and client_obj is not False: # Found the client. Now check if they are still in their dails quota ! # We only allow as many results as assigned to the client. # We want the option to change this value for certain users that have # big volume sites. if the count is 0 that means we allow unlimited calls. # We allow 0 clients as our site uses this api too for the javascript calls # Get the current date and year current_date = int(time.strftime("%d")) current_month = int(time.strftime("%m")) current_year = int(time.strftime("%Y")) # get the calls search_apis_calls = dal.search_api_calls(client_obj, current_date, current_month, current_year) # Local Var with Limit daily_limit_local = search_apis_calls.count() # If the count of calls bigger than 0 if search_apis_calls is not False and ( client_obj.daily_limit == 0 or daily_limit_local < client_obj.daily_limit ): # Check if the Q parameter was given for a search if self.request.get('q') and len(self.request.get('q')) >= 3: # Well let's do some searches ! # Trim and check the search term. We want to avoid any errors and keep # it consistant for all the providers search_term = str(self.request.get('q')).strip().replace(' ', '').replace('\t', '').replace('\n', '').replace('\r', '') # Insert info about the call inserted_call = {} # Get all the searchable DAL's in # the order that we will search them. providers = dal.approved_providers() # Run the Search Runner to request from all providers search_raw_response = runner.search(self.request, search_term, providers) # Results # We just show quick info. Such as name, pic and some basic info. # If the user wants to send a E-Mail they can do so with the specified contact url. # This is to protected the E-Mail of address of the owner. (search_obj, search_responses) = dal.search_by_token(str(search_raw_response.token)) # Make the result text result_text = 'notfound' # Check if the response was a success if search_obj.provider_success_responses > 0: result_text = 'found' # Create the results success_results = [] failure_results = [] # Loop and add the diffrent results for response in search_responses: # Create the Provider Obj provider_obj = {} provider_obj['id'] = response.provider.key().id() provider_obj['name'] = response.provider.name provider_obj['website'] = response.provider.website provider_obj['logo'] = response.provider.logo_url(128) if response.status == runner.ProviderResponse.STATUS_FOUND: # Parse to get details data = res = json.loads(response.parsed_response) # Assign params res['owner_name'] = data['owner']['name'] res['contact_url'] = 'http://www.identichip.org/apis/v1/contact?token=' + str(self.request.get('token')) + "&key=" + str(search_obj.token) + "&provider=" + str(response.provider.key()) # Remove owner details del res['owner'] # Assign provider params res['provider'] = provider_obj # Add to list success_results.append(res) elif response.status not in [runner.ProviderResponse.STATUS_FOUND, runner.ProviderResponse.STATUS_NOTFOUND]: # Add the failed provider failure_results.append(provider_obj) # Well we just added a count daily_limit_local += 1 # Redirect to the Search's token so the user # can view the result. This also keeps them away from # executing this page multiple times as that would # be bad! self.response.out.write(json.dumps({ 'result': result_text, 'token': str(search_obj.token), 'url': 'http://www.identichip.org/view/' + str(search_obj.token), 'success': success_results, 'failed': failure_results, 'daily_limit': client_obj.daily_limit, 'remaining_limit': int(client_obj.daily_limit) - daily_limit_local })) # Save client call client_call = schemas.APICallCount() client_call.date = current_date client_call.month = current_month client_call.year = current_year client_call.uid = search_term client_call.client = client_obj client_call.search = search_obj db.put_async(client_call).get_result() # Save for Stats. This is done Async. This is the global search stat dal.update_or_add_search_counter(self.request, search_raw_response).get_result() else: # No UID to search ??? self.response.out.write(json.dumps({ 'error': 'No q parameter was given ! This parameter tells us what UID to search for. Which is quite imporant ... Please see the developer documentation for this at http://www.identichip.org/developer' })) else: # Inform them self.response.out.write(json.dumps({ 'error': 'This Token has exceeded it\'s daily call limit of ' + str(client_obj.daily_limit) + ". If your client requires more please get in contract with us as we can arrange custom plans." })) else: # Inform them self.response.out.write(json.dumps({ 'error': 'No such client found. Invalid Token !' })) else: # Inform them self.response.out.write(json.dumps({ 'error': 'No Client token was given. Please login and create a client to start searching from our providers' }))