Kivy app (on android) crashes when attempting to use google directions api - urllib2

I new to Kivy (and relatively new to Python) and I am having a problem getting UrlRequests to work. In particular, I am trying to use the google directions api in an App for android.
First of all, the code works (completely) when I run the main.py file through python.
The app also successfully builds and deploys to my phone using buildozer. The app loads and runs right up to the point where you press a button to launch a urlrequest, at which point the app just closes.
So I believe the problem is this button. The full details of the button are somewhat unnecessary to explain now I think, but basically it uses a function (like below) several times to return the distance between places.
import urllib2
#the google api key
google_api_key = '...'
def distance_checker(origin, destination):
# This function outputs the distance between two places in meters
api_key = google_api_key
url = 'https://maps.googleapis.com/maps/api/directions/json?origin='
start = origin.replace(' ', '%20')
end = destination.replace(' ', '%20')
final_url = url + start + '&destination=' + end + '&mode=walking' + '&key=' + api_key
json_obj = urllib2.urlopen(final_url)
data = json.load(json_obj)
return data['routes'][0]['legs'][0]['distance']['value']
In my buildozer.spec file I do have 'android.permissions = INTERNET' included.
I also had my app attempt to access google using a function of the form (submitted by user: 10flow, on Pinging servers in Python),
import os
def ping_function(self):
hostname = "google.com" #example
response = os.system("ping -c 1 " + hostname)
#and then check the response...
if response == 0:
self.box.add_widget(Label(text=(hostname + ' is up!'), size_hint_y=None, height=40))
else:
self.box.add_widget(Label(text=(hostname + ' is down!'), size_hint_y=None, height=40))
For clarity, the 'box' used above is for a ScrollView widget. This function does work in the app in android (i.e. it does create a Label saying 'google.com is up!'). So this would lead me to believe that accessing the internet itself is not the problem: the problem is either using a google api, or the using of urllib2 (that make sense?).
I also wrote a function which does the url query using UrlRequest instead of urllib2, but that had the same problem in the end (works on linux, not on android).
So I imagine the problem is using google apis. And I think it has something got to do with adding 'google-play-services_lib/' as an android.library reference in the buildozer.spec file.
If what I have said so far makes sense, could anyone comment on the google api/google-play-services_lib issue? I'm really not that familiar with apis in general, and am somewhat out of my depth. Or perhaps this isn't the issue, and I have missed something obvious.
Anyway, thanks in advance.
EDIT
I think I have narrowed down the problem somewhat. I can use apis that do not require a key, and I cannot use apis that do need a key. Posts like How to get google map apikey in android lead me to believe I just need to add the google api key (in the case of the google directions api) to the android meta data in the buildozer.spec file. I have unsuccessfully tried several variations of the following,
# (list) Android application meta-data to set (key=value format)
android.meta_data = com.google.android.maps.v2.API_KEY=AI...
If anyone could tell me what I am doing wrong it would be very helpful!
Thanks.

So for others and posterity, I found an answer through the Kivy users forum (http://kivy.org/#forum, question: Problems with UrlRequest with an api that needs an api key).
The issue was I was trying to access a https url, and hence needed to build the android apk using openssl. No need for android meta data or google play services, just add openssl to the requirements in the buildozer.spec file.
requirements = openssl,kivy
Once it was discovered that openssl was the issue, there was one more problem to overcome in that buildozer attempted to download an openssl tar file that no longer existed on the openssl.org webpage. However, one can edit the openssl version buildozer attempts to download in your_project/.buildozer/android/platform/python-for-android/recipes/openssl/recipe.sh . You will also need to update the MD5 value in that file.
Hopefully this helps someone in the future.

Related

What is the correct way of getting an app key in google?

I'm trying out a simple code I found using www::google::customsearch. I know that google and yahoo has already change its policy in allowing these searches.
use strict;
use warnings;
use Data::Dumper;
use WWW::Google::CustomSearch;
my $api_key = 'Your_API_Key';
my $cx = 'Search_Engine_Identifier';
my $engine = WWW::Google::CustomSearch->new(api_key => $api_key, cx => $cx);
print Dumper($engine->search("Google"));
I am not sure if this module will work. I was just trying to test it. This is a sample from cpan. I tried running the code I keep getting a missing argument which is the api key.
This is so far what I have done. I have signed in google and created a custom search engine. I copied the search engine reference code. I have tried the example code in javascript. I placed it in a sample html. It works.
I have also signed in google and turned on custom search engine api, and generated an app key.
What is the correct step in getting an application key?
I tried running the code I keep getting a missing argument which is the api key.
You did not try to execute the given code as it is, did you? You are supposed to pass the actual key in below line.
my $api_key = 'Your_API_Key';
Your_API_Key should be replaced with the key you get from Google API console.
What is the correct step in getting an application key?
Quoting from the documentation on how to find it.
The JSON / Atom Custom Search API requires the use of an API key,
which you can get from the Google APIs console. The API provides 100
search queries per day for free. If you need more, you may sign up for
billing in the console.
The official Google API document can be found here. For more
information about the Google custom search, please click here.

Google+ .Net API - Getting Authenticated and retrieving profile

I'm trying to get a users profile information for google+ via the .NET API but am having trouble.
Does anyone know if they have changed how the special ID "me" works?
In the documentation it says this can be used as a special ID to get the currently authenticated users information however this throws a 404 from both the API in my code and on Google's own test page https://developers.google.com/+/api/latest/people/get. I was logged in when trying this.
Does anyone know how to get the user ID as I would happily use that instead of me but it isn't returned after the user authenticates as far as I can see (just an authcode)?
I also tried using user IDs returned when using the standard .net Oauth stuff but it isn't the correct ID, I assume it is for something else.
As for my method of getting to this stage, I first downloaded the example files here: http://code.google.com/p/google-api-dotnet-client/wiki/GettingStarted
They don't have a plus example so I took the Tasks.ASP.NET.SimpleOAuth2 example and swapped out tasks (which worked fine) for the plus equivalent.
I also tried rolling this into my own project.
Neither worked. I get the user forwarded to Google where they give me access fine and then when I return they are authenticated successfully as far as I can see, however when I call service.People.Get("me") it returns a 404.
If anyone could help with the above questions (using me, or gettign the user ID) I would appreciate it.
To the moderator who closed the initial version of this question, I have tried to make this as direct a question as possible so please don't close it. This is a legitimate question I would really like help getting to he bottom of.
This is now out of date given recent platform updates. Although the plus.me scope still exists and this code will work, you should be using the plus.login scope for retrieving profile data in C#. For a great way to get started with retrieving and rendering profile information, please start from the Google+ C# quick start available here:
https://developers.google.com/+/quickstart/csharp
First off, the 'me' id still works and is unchanged. The way that it works is:
You authenticate the user using a standard OAUTH2 flow
You use the library to perform a People.get with the special value 'me'
The 404 error code is a little troubling, this means that the client isn't finding the endpoint. To debug this, you might want to use a packet sniffer like fiddler to see what the actual URL it's querying is.
Anyways, how about some C# code. The following example shows how to use the plus service to get the currently authenticated user (assuming you have authenticated someone). What's different from your snippet is that you need to form a get request for the API call, then run fetch on the get request. I've included the following example, for getting 'me', and the following code works:
var auth = CreateAuthenticator();
plusService = new PlusService(auth);
if (plusService != null)
{
PeopleResource.GetRequest prgr = plusService.People.Get("me");
Person me = prgr.Fetch();
}
All of the configuration of the server and getting a client working is pretty hard and pasting all of the code here would be less helpful than just giving you a sample.
And so... I have written a sample application that demonstrates how to do this and also includes a wrapper that makes it easier to develop using the Google+ API in C#. Grab it here:
Google+ C# Server-Side demo and library
Seems you need to use:
Person test = service.People.Get("me").Fetch();
and not
req = service.People.Get("me");
Person test = req.Fetch();
Even though they seem to be identical the first works and the second doesn't.
Still not sure why google's own page doesn't work though. Now to find out how to add things to the scope like birthday.

Zend_Gdata_ClientLogin::getHttpClient Issues

I am working on a project using the Youtube APIv2.
I am using the API through Zend Framework via Zend Gdata.
My application is querying the youtube api, getting a video feed then for each entry getting the name, thumbs, views, duration and tags for each video entry.
As announced by Google (http://apiblog.youtube.com/2012/08/video-tags-just-for-uploaders.html) now to get the video tags of each video entry the youtube api request as to be authenticated by the user that owns the videos on youtube in order to retrieve these video tags.
What i've done is simply adding a developer key and a httpClient object when I init the *Zend_Gdata_YouTube* object, like that :
$developerKey = 'mydevkey';$authenticationURL = 'https://www.google.com/youtube/accounts/ClientLogin';$idApplication = 'my_app_id';$idClient = null;$httpClient = Zend_Gdata_ClientLogin::getHttpClient( $username = 'google_account_email', $password = 'google_account_pass', $service = 'youtube', $client = null, $source = 'my_app', $loginToken = null, $loginCaptcha = null, $authenticationURL);$this->yt = new Zend_Gdata_YouTube($httpClient, $idApplication, $idClient , $developerKey);$this->yt->setMajorProtocolVersion(2);
I tested this piece of code in my project locally inside Mamp Pro and it works perfectly fine, retreiving the video tags as it should be, meaning that the code works.
My problem starts when i wan to put my code on my production server, the *Zend_Gdata_ClientLogin::getHttpClient* object is not working and keeps giving me the error code "Authentication with Google failed. Reason: BadAuthentication"
I checked if someone else was having my problem and i came to this article "http://apiblog.youtube.com/2011/03/clientlogin-fail.html", but neither of the 4 scenarios are similar to my problems.
Could someone help me ? Does my production server is missing something in terms of modules or authorizations (i check it doesn't looks like it).
Thank you.
I had the same problem. My script was working locally, but not in production.
Change your password for a new one and run your script in production first.

Script to download Google web history

How does one write a script to download one's Google web history?
I know about
https://www.google.com/history/
https://www.google.com/history/lookup?hl=en&authuser=0&max=1326122791634447
feed:https://www.google.com/history/lookup?month=1&day=9&yr=2011&output=rss
but they fail when called programmatically rather than through a browser.
I wrote up a blog post on how to download your entire Google Web History using a script I put together.
It all works directly within your web browser on the client side (i.e. no data is transmitted to a third-party), and you can download it to a CSV file. You can view the source code here:
http://geeklad.com/tools/google-history/google-history.js
My blog post has a bookmarklet you can use to easily launch the script. It works by accessing the same feed, but performs the iteration of reading the entire history 1000 records at a time, converting it into a CSV string, and making the data downloadable at the touch of a button.
I ran it against my own history, and successfully downloaded over 130K records, which came out to around 30MB when exported to CSV.
EDIT: It seems that number of foks that have used my script have run into problems, likely due to some oddities in their history data. Unfortunately, since the script does everything within the browser, I cannot debug it when it encounters histories that break it. If you're a JavaScript developer, use my script, and it appears your history has caused it to break; please feel free to help me fix it and send me any updates to the code.
I tried GeekLad's system, unfortunately two breaking changes have occurred #1 URL has changed ( I modified and hosted my own copy which led to #2 type=rss arguments no longer works.
I only needed the timestamps... so began the best/worst hack I've written in a while.
Step 1 - https://stackoverflow.com/a/3177718/9908 - Using chrome disable ALL security protocols.
Step 2 - https://gist.github.com/devdave/22b578d562a0dc1a8303
Using contentscript.js and manifest.json, make a chrome extension, host ransack.js locally to whatever service you want ( PHP, Ruby, Python, etc ). Goto https://history.google.com/history/ after installing your contentscript extension in developer mode ( unpacked ). It will automatically inject ransack.js + jQuery into the dom, harvest the data, and then move on to the next "Later" link.
Every 60 seconds, Google will force you to re-login randomly so this is not a start and walk away process BUT it does work and if they up the obfustication ante, you can always resort to chaining Ajax calls and send the page back to the backend for post processing. At full tilt, my abomination script collected 1 page a second of data.
On moral grounds I will not help anyone modify this script to get search terms and results as this process is not sanctioned by Google ( though not blocked apparently ) and recommend it only to sufficiently motivated individuals to make it work for them. By my estimates it took me 3-4 hours to get all 9 years of data ( 90K records ) # 1 page every 900ms or faster.
While this thing is going, DO NOT browse the rest of the web because Chrome is running with no safeguards in place, most of them exist for a reason.
One can download her search logs directly from Google (In case downloading it using a script is not the primary purpose),
Steps:
1) Login and Go to https://history.google.com/history/
2) Just below your profile picture logo, towards the right side, you can find an icon for settings. See the second option called "Download". Click on that.
3) Then click on "Create Archive", then Google will mail you the log within minutes.
maybe before issuing a request to get the feed the script shuld add a User-Agent HTTP header of well known browser, for Google to decide that the request came from that browser.

Using Google maps API via SSL

So, I know just recently that google maps API is now available in SSL (here).
My question is, how do I retro-fit my http google maps api script to use this?
So my http Google maps API script call looks like this:
http://maps.google.com/maps?file=api&v=3&sensor=false&key=########
They suggest via this link that to use SSL it should be this:
https://maps-api-ssl.google.com/maps/api/js?v=3&sensor=false
I've tried retro-fitting this into my old URL format like so:
https://maps-api-ssl.google.com/maps/api/js?v=3&sensor=false&key=########
but that no longer displays the map.
Does anyone have any suggestions on what the URL should be?
Thanks
Try this line:
https://maps.google.com/maps/api/js?v=3.5&sensor=true
Google btw suggests that you explicitly enter what version of the api you are going to use. Just entering v=3 will always return the latest version, at the moment 3.5. I believe that the current stable version is 3.3.
As Trott wrote in his answer, api key is no longer needed.
You don't need an API key to use v3, but I suppose it probably doesn't hurt. General things to try:
Open your browser's JavaScript console and see if it is reporting any problems when you load the page.
Remove the API key
Change & to just &
Copy and paste the exact link text you put above into your code, because that link text is working for me. I'm referring to this:
https://maps-api-ssl.google.com/maps/api/js?v=3&sensor=false&key=########
Of course, change ######## to your API key (or just remove it altogether).