Saturday, April 09, 2016

How to Post to Blogger - Blogspot using Google API in Python automatically

This blog explains the end-to-end of the steps needed to write a Python program that will write a "post" to a blog on Google's blogger.com
Why? This is part of a step to automate writing blog posts. For example, you want to post a blog every minute to say:
    Today - at this exact minute 12:05:00, the temperature is 27'C
In this example the time and temperature data are obtained somewhere and you can programmatically construct the sentence above.
However, it will be very tedious to login to blogger, click on many buttons, write the content and publish the post every minute.
A program can be setup to login automatically and post the sentence above to the blog automatically - that is the goal here.

GOAL:
To write a Python program that will automatically publish blogger/blogspot post

METHOD:
The combination of the following technologies are used:
- Python programming language
- Blogger/Blogspot blog providers
- Google API for Python
- OAuth 2.0 Google Authorization


PREREQUISITE:
1. Python v2.x - assume you have this installed - instructions on how to install and use python is beyond the scope of this post.
2. Blogger.com / blogspot.com account - These two names are the same free Blog site owned by Google. It is assumed you already have an account and know how to post blogs by logging in and posting a blog manually. Instructions on how to setup and use a blog the normal ways are not covered here.


PREPARATION:

1. On a CMD prompt / terminal, do:
pip install --upgrade oauth2client
pip install --upgrade google-api-python-client
https://developers.google.com/api-client-library/python/apis/blogger/v3#sample
https://developers.google.com/blogger/docs/3.0/api-lib/python#sample

2. Go to website below to get 'api_name', 'api_version'
Supported Google APIs: https://developers.google.com/api-client-library/python/apis/
api_name=blogger    api_version=v3
api_name=drive      api_version=v3




OAUTH AUTHORIZATION:

These two websites are good to get a reasonable understanding, but ultimately does not provide direct instructions.
    https://developers.google.com/blogger/docs/3.0/using#auth
    https://developers.google.com/identity/protocols/OAuth2#basicsteps

The three main types of Credentials are:
1. API Keys
2. OAuth 2.0 client IDs
3. Service account keys

Go to https://console.developers.google.com
The interface is not very good at directing what to do next.
On the left panel are: Overview,  Credentials
On the top right horizontal menu of items, there is a Drop-Down icon
--- Click on the Drop-Down icon to "Manage all projects" or "Create Project"
--- If new here, then choose Create Project,
--- Note that you can enter quite different values for Project Name and Project ID.

Coming back to the main page, click Overview
--- Now the main area has: "Google APIs" and "Enabled APIs"
--- Click on the "Google APIs" to show a list of popular APIs.
--- If Blogger API is not listed, type Blogger on the search text field.
--- Then click Blogger and click Enable (if not enabled already)
--- Going back some pages, now click "Enabled APIs". On this page, check that "Blogger API v3" is listed.

Coming back to the main page, click Credentials (just below Overview)
--- The top submenu has: "Credentials", "OAuth consent Screen", "Domain Verification"
--- Click on Credentials.
--- for OAuth 2.0 client IDs
------ To create manually, click on "Create Credentials", choose OAuth Client ID, choose Other as Application type.
------ To create automatically, click on "Create Credentials", choose "Help Me Choose".
--------- Then in the drop down, choose Blogger API, choose calling the API from "Other UI(Windows)", choose "User Data"
------ At the end, the credentials is downloaded, eg client_secret_<client_id>.json, and the content is like:
                 {"installed":{"client_id":"
--- for Service Account Keys
------ To create manually, click on "Service Account Keys", choose a service account (create one if needed), choose JSON, click Create.
------ To create automatically, click on "Create Credentials", choose "Help Me Choose".
--------- Then in the drop down, choose Blogger API, choose calling the API from "Other UI(Windows)", choose "Application Data"
------ At the end, the credentials is downloaded, eg <project>-<keyID>.json, and the content is like:
{
  "type": "service_account",
  "project_id": ".......",
  "private_key_id": "..................",
  "private_key": "-----BEGIN PRIVATE

Since this project is about automated program that writes to the blog, the credentials should not involve any interaction - in this case, create and use the "Service account keys"
The "OAuth 2.0 client IDs" also works but requires clicking a button and copying a "code" to the python program. This is shown to work - but this is less suitable for our goals.


SCOPE:
Before the actual coding to use the APIs, the authorization process also need to know the scopes of your program.
Here are some scopes for the Blogger API and the Google Drive API:

Blogger API, v3
https://www.googleapis.com/auth/blogger Manage your Blogger account
https://www.googleapis.com/auth/blogger.readonly View your Blogger account
Drive API, v3
https://www.googleapis.com/auth/drive View and manage the files in your Google Drive
https://www.googleapis.com/auth/drive.appdata View and manage its own configuration data in your Google Drive
https://www.googleapis.com/auth/drive.file View and manage Google Drive files and folders that you have opened or created with this app
https://www.googleapis.com/auth/drive.metadata View and manage metadata of files in your Google Drive
https://www.googleapis.com/auth/drive.metadata.readonly View metadata for files in your Google Drive
https://www.googleapis.com/auth/drive.photos.readonly View the photos, videos and albums in your Google Photos
https://www.googleapis.com/auth/drive.readonly View the files in your Google Drive
https://www.googleapis.com/auth/drive.scripts Modify your Google Apps Script scripts' behavior

*** A Complete list of scopes for all Google APIs (not just Blogger and Drive), can be found in:
https://developers.google.com/identity/protocols/googlescopes
- title "OAuth 2.0 Scopes for Google APIs"


CODE in Python:
1. The code below is complete end to end. When run, it will handle the authorization, then send some text, to be posted to a blogger site and the json response is captured.
2. There may be more import statements than necessary.
3. The code will NOT work as is because the __blogID__ is not real and the <blah>.json files is not the real filenames. If these values are replaced with proper values, the code should work.
4. The code also shows to options of OAuth. The first uses "OAuth 2.0 for Server to Server Applications" which does not need interaction. The second, which is commented out, uses "Client Secrets", which pops-up a browser, then the operator needs to copy the code and paste it on the terminal where the python code is running.

<code><pre>
import os
# OAuth 2.0 for Installed Applications
from oauth2client.client import flow_from_clientsecrets
# OAuth 2.0 for Server to Server Applications
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
from oauth2client.client import flow_from_clientsecrets
import json
import webbrowser
import httplib2

from apiclient import discovery
from oauth2client import client
from apiclient.discovery import build
from googleapiclient import sample_tools

__blogID__='99999999999999999999'

# Using OAuth 2.0 for Server to Server Applications
# https://developers.google.com/api-client-library/python/auth/service-accounts#authorizingrequests

scopes = ['https://www.googleapis.com/auth/blogger.readonly']
credentials = ServiceAccountCredentials.from_json_keyfile_name('<project>-<keyID>.json', scopes)
http_auth = credentials.authorize(Http())
# THis returns no errors - so what's next????

"""
# Client Secrets
# https://developers.google.com/api-client-library/python/guide/aaa_client_secrets
flow = flow_from_clientsecrets('client_secret_<client_ID>.json',
                               scope='https://www.googleapis.com/auth/blogger',
                               redirect_uri='urn:ietf:wg:oauth:2.0:oob')
# This section copied from https://developers.google.com/api-client-library/python/auth/installed-app#example
auth_uri = flow.step1_get_authorize_url()
webbrowser.open(auth_uri)
auth_code = raw_input('Enter the auth code: ')
credentials = flow.step2_exchange(auth_code)
http_auth = credentials.authorize(httplib2.Http())
# THis returns no errors - so what's next????
"""

service = build('blogger', 'v3', http=http_auth)   # (api_name, api_version)

text = \
'{ \
    "kind": "blogger#post", \
    "blog": { \
        "id": "999999999999999" \
    }, \
    "title": "A new post", \
    "content": "With <b>new</b> content..." \
}'

parsed = json.loads(text)
print json.dumps(parsed , indent=4, separators=(',', ': '))

request = service.posts().insert(blogId=__blogID__, body=parsed )
response = request.execute()
print json.dumps(response , indent=4, separators=(',', ': '))
</pre></code>





APPENDIXES:
There is a lot of information on this subject, to the extent that it has become confusing and difficult to understand.
The instructions in this blog post just give the minimum steps without too much explanations with the aim of reducing the confusion.
However, to gain an understanding after the fact, the list of websites is given here as a reference:

https://developers.google.com/api-client-library/python/guide/aaa_oauth#oauth-20-explained
- EXCELLENT page - title "OAuth 2.0" - part of "API Client Library for Python"
- examples of Python code to use OAuth 2.0 to connect to Google APIs.

https://developers.google.com/identity/protocols/OAuth2InstalledApp#choosingredirecturi
- talks about "redirect_uri" in the code. The main page is called "Using OAuth 2.0 for Installed Applications"

https://support.google.com/cloud/answer/6158849?hl=en#serviceaccounts
- not that useful

https://developers.google.com/api-client-library/python/auth/service-accounts
- title "Using OAuth 2.0 for Server to Server Applications", part of the "API Client Library for Python"
- OAuth 2.0 can be for "Web Server Application", "Installed Applications", "Server to Server Applications".
- For this goal of automatically posting to Blogger, the "Server to Server Applications" is the most relevant.

https://developers.google.com/blogger/
- Intro to the Blogger API

https://developers.google.com/blogger/docs/3.0/reference/#Pages
- Blogger API reference

About accessing Google APIs for Blogger
https://developers.google.com/blogger/docs/3.0/libraries
https://developers.google.com/resources/api-libraries/documentation/blogger/v3/python/latest/
https://developers.google.com/api-client-library/python/
https://developers.google.com/apis-explorer/#p/blogger/v3/

Friday, March 11, 2016

Twitter - How to change names

In Twitter there are multiple names. The names can be displayed to all users as follows:
----------------------
My Display Name
@myname
----------------------

On some mobiiles, the Twitter interface would only allow you to change the first line of name.
To change that first line name, here are the steps.
1. Open the Twitter app
2. Touch on the 'Triple vertical dots"on the top right corner - this will display a drop down list
3. On the drop down list on the top right, touch the first line - which is showing the current name.
4. On the new page, touch the "Edit Profile"
5. On another new page, touch the "Name" field to edit.

The steps above only allow the first line to be changed. So now it can be something like:
----------------------
My NEW Display Name
@myname
----------------------

So the second line with the @ sign is not changed yet. To change this, go to a Computer, then open a Browser.
1. In the browser, go to Twitter's website.
2. Login to your Twitter account.
3. Click on your icon/photo on the top right corner
4. In the Drop Down list that appears, click Settings.
5. In the Settings page, click Account on the left navigation panel
6. The main panel in the middle will show Account, and under it is a text field for Username.
7. Enter the new "Username" and this would appear with @Username.

8. In addition, go back to the Home Page
9. Click on your icon/photo on the top right corner.
10. Click on the first line, which shows your name.
11. This opens a new page. Click on the Edit Profile,
12. Then fill in the text field that pop up - this would be the first line name.

----------------------
My NEW Display Name
@NEWusername
----------------------

Wednesday, February 10, 2016

Outlook Gmail IMAP stuck in syncing endlessly

I'm trying to help someone that is using a newish Outlook version, to read their emails from Gmail. I think the method is set as IMAP, rather than POP. The problem is that when Outlook is opened, the bar at the bottom says syncing and it never stops, even after overnight session. Another symptom is that new email cannot be received.

After some googling, (going to visit soon), I'm just putting a few links here which may be helpful.







Friday, January 29, 2016

Notes Raspberry Pi

NotesRaspberryPi
================

How to setup a brand new Raspberry Pi
https://www.raspberrypi.org/help/quick-start-guide/

Various resources to teach/learn RaspberryPi. Also contain some Python lessons
https://www.raspberrypi.org/resources/learn/

Official Documentation
https://www.raspberrypi.org/documentation/

Other interesting setup articles
http://www.everydaylinuxuser.com/2015/03/setting-up-raspberry-pi-2.html
http://www.everydaylinuxuser.com/2014/03/connect-to-raspberry-pi-from-hp.html

Sunday, January 03, 2016

Windows 10 - Adding / Creating Local User Instead of Microsoft User

Back in the days (not apologizing for reminiscing) of Windows XP (or maybe even Windows 7) or earlier, adding a user is a simple process of adding a user.

With Windows 8 (I hope not 7) onwards, there seems to be a deliberate attempt to coerce (force) people to open up Microsoft accounts and create such cloud users, even when people are just trying to use their Windows computers locally (not in the cloud). Then in Windows 8, you must read the fine print and try to choose to create or add a "Local User". So a "Local User" is actually what a normal user is, in the previous Windows version - but now we have to remember to use "Local Users" if we just want a normal user on  a computer.

In Windows 10, this is much more difficult, frustrating and annoying. So previous Windows just need: Go to Control Panel -> click Users -> Add user.
But now the problem is so complicated, bordering on deceiving, I just cannot stand it and have to share this process here so that people can get help.

Step 1: Use the normal process of going to Control Panel, or searching for User, to land on this dialog below. Or Control Panel -> User Accounts -> User Accounts (not typo) -> Manage Accounts -> click on "Add a new user in PC Settings"

Then click "Family and Other Users".
Why why why they can't just say "users"?

Then click on "Add someone else to this PC"
(What if this is my family member, but they don't have Microsoft account - sic)

Don't put email address, don't click next.
Instead click "I don't have this person's sign-in information"
(Why why why - well I have this person's sign in - but I refuse to use their Microsoft account. I just want to create them as a "Local User" - phethhhh  :p  )


Finally - almost there. Still don't fall into the trap of giving your details and email.
Click "Add a user without a Microsoft Account"

Home Run !!! (Exactly the fourth / home base)
Now this is more like the usual creation of a normal Windows user.
Go ahead and give it a funny user name - as all computer users have done since the dawn of computing - instead of giving your email account.

Missing Windows 10 Start Key functionality

Beware - Windows 10 - Broken Windows Start Key functionality.
Normally, the Start button on the lower left corner of the Desktop, when pressed, will bring up a list of apps, and some tiles.

When this problem hits (out of nowhere), pressing (left clicking) the Windows Start button has no effect. Double click the Search bar next to it - still sort of works sometimes. Right-clicking the Start button reveals a text based list of thinks that you can do - including poweroff. So all is not lost, but it is very frustrating to see the normal functionality disappear. (see the image below to view the new text-based list of items when right click).



Solved - but don't know which of the following did the trick. Googling gave two solutions.
1 ) Open CMD prompt as Administrator and run:  SFC /scannow
2) Open Powershell as Administrator and run the command shown in the webpage in the image below
3) Restart the PC
All is back to normal. I did all three in sequence. Don't really know if the restart at the end actually solves the problem or all three together.