Archive | Programming

Using cURL, BASH and Google oAuth to access Google Analytics

In this previous post, I used cURL (the command line version) to interact with Google Analytics. I wanted to do the same thing but using oAuth. I took a lot from this page, but there were a few things that I couldn’t get working, and a few things I didn’t know.

Follow Steps 1-6 on this page. These are steps that you need to follow to get your app registered with Google

In step 6, copy down the code, and keep track of it. It needs to be reused every time you need to get a new token. If you loose it, then you need to run step 6 over again. I didn’t know that.

Here is my script. I will jump through the code below it.

#!/bin/bash
CODE="4/v6xr77ewYqhvHSyW6UJ1w7jKwAzu&amp"
CLEINTID="1234567890.apps.googleusercontent.com"
HEADER="Content-Type: application/x-www-form-urlencoded"
CLIENTSECRET="aBcDeFgHiJkLmNoPqRsTuVwXyZ"
REDIRECTURI="urn:ietf:wg:oauth:2.0:oob"

# I keep the ACCESS_TOKEN and the REFRESH_TOKEN in a file.
if [ -s ~/.google ];then
	ACCESS_TOKEN=$(cat ~/.gauth | grep access_token | awk -F"," '{print $2}' | tr -d ' ')
	REFRESH_TOKEN=$(cat ~/.gauth | grep refresh_token | awk -F"," '{print $2}' | tr -d ' ')
else
	# not used before
	NEWTOKEN=$(curl -s -d "code=$CODE&redirect_uri=$REDIRECTURI&client_id=$CLEINTID&scope=&client_secret=$CLIENTSECRET&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token)
	ACCESS_TOKEN=$(echo $NEWTOKEN | awk -F"," '{print $1}' | awk -F":" '{print $2}' | sed s/\"//g | tr -d ' ')
	REFRESH_TOKEN=$(echo $NEWTOKEN | awk -F"," '{print $4}' | awk -F":" '{print $2}' | sed s/\"//g | sed s/}// | tr -d ' ')
	echo access_token , $ACCESS_TOKEN > .google
	echo refresh_token , $REFRESH_TOKEN >> .google
fi
EXPIRED=$(curl -s https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=$ACCESS_TOKEN | grep 'invalid_token')
if [ "$EXPIRED" ]       
then
	echo "EXPIRED"
	REFRESHRETURN=$(curl -s -d "client_secret=$CLIENTSECRET&grant_type=refresh_token&refresh_token=$REFRESH_TOKEN&client_id=$CLEINTID" https://accounts.google.com/o/oauth2/token)
	ACCESS_TOKEN=$(echo $REFRESHRETURN | awk -F"," '{print $1}' | awk -F":" '{print $2}' | sed s/\"//g | tr -d ' ')
	echo access_token , $ACCESS_TOKEN > .gauth
	echo refresh_token , $REFRESH_TOKEN >> .gauth
fi 
AUTH=$ACCESS_TOKEN
# now in your curl code to retrieve the google analytics data, you use --header "Authorization: OAuth $AUTH"

Lines 1-6: I am setting up my variables with data as described in the linked post.
Lines 8-11: I keep track of the current access token and the refresh token in a config file. If the file exists then parse out the values
Lines 12-19: This is the first time this has been run, so I need to create the file, and put in it a new token and the refresh token. Note the refresh token needs to be saved, and is only given to you once. I did not know that.
Line 20: checks to see if the access token is expired.
Lines 21-28: if the access token is expired, use the refresh token to get a new access token and then save it to the file.

That is it. I hope to translate into PowerShell next – I am sure this code exists, but this is how I learn.

Hope this helps someone.

Knockout alternate formattting

I was using KnockoutJS to loop through and display some data. I wanted to apply some alternate formatting on every other row. I used this syntax containing the MOD operation to achieve the formatting I wanted.

<!-- ko if: $index() % 2 === 0 -->

The other thing I learned was that $index() is observable, so I can +1 it? I believe that is right.

The following were some sources that clued me in:

http://jsfiddle.net/KuJBv/11/
https://groups.google.com/forum/#!msg/knockoutjs/ElVix0ksXh8/awkTFYewitAJ

How I am using a Delegate control, code in a Document library, and jQuery to customize SharePoint 2010

In this post, I showed how to put a delegate control at the top over every page, and in the control add the links to the jQuery libraries. This is nothing new, there are many articles that show how to do this. I took this a step further and I included code to do the following:

  1. Determine the current page’s relative URL (where the delegate control is running) and put that value in a Variable
  2. Take that variable and change the relative URL’s forward slashes (“/”) to underscores (“_”), and change “.aspx” to “.txt”
  3. Look for a file in a document library with a name that matches the variable created above and insert it’s contents into the additional page header

For example if  I am browsing to http://sharepoint.company.com/Lists/Announcements/AllItems.aspx, and there is a file in the desiganted Document library named “_lists_announcements_allitems.txt” then it’s contentens will show up in the addition page header.

Some of the benefits I have found with my methods

  1. All client side code is kept in one place, and you can easly figure out which file is being used on each page
  2. The Document Library can have versioning, so you can rollback changes
  3. Linked CEWP can be kept in the same place
  4. It is easy to edit text, js and css files in SharePoint Designer, rather than in CEWP
  5. Now it is a snap to chop up a NewForum.aspx via jQuery
  6. It is easy to extend the code so that a file is included across all pages, making it easy to add a new js library to the entire site

Here is the code I am using in the Delegate Control (ascx)

string CurrentSiteRelativeURL = CurrentUrl.ToLower().Replace(CurrentWeb.Url.ToLower(), "");
string CustomFileName = CurrentSiteRelativeURL.Replace("/", "_");
string PageSpecificHeaderIncludes = CurrentWeb.Url + "/DocumentLibraryWithCodeInIt/" + CustomFileName.Replace(".aspx", ".txt");

Response.Write("<!--PageSpecificHeaderIncludes:" + PageSpecificHeaderIncludes + "-->");
    if (CurrentWeb.GetFile(PageSpecificHeaderIncludes).Exists == true)
    {
        SPFile tempFile = CurrentWeb.GetFile(PageSpecificHeaderIncludes);
        StreamReader reader = new StreamReader(tempFile.OpenBinaryStream());
        string myText = reader.ReadToEnd();
        reader.Close();
        Response.Write(myText);
    }

Anyone else doing anything like this? Thoughts?

Using cURL to pull Google Reader starred items – Part 1 xpath

A while ago, I wrote a post about using ruby to parse the xml feed of shared starred items in Google Reader. One thing that I did not like about this solution was that I could not get the URL AND mark the item as un-starred. Since I had been playing with REST in these two prior posts, I figured I could re-write my code to pull down starred item’s URLs, and mark them as un-starred. I wanted to eliminate ruby, as I just don’t use it that often and I feel like I am re-inventing the wheel every time. This too a lot longer than I thought it would, but I figured it out (I think)

As this article explains, you can share out your Google reader starred items. First step was the find the needed values from this XML feed and put the values into variables. I turned to xpath (xpath is installed by default on OS X, it is part of the Perl library XML::XPath).

For the second part of this tutorial, where we mark the item as “un-starred”, we need 2 variables form the Xml feed: id & source. My end goal was to put these URLs into Together.app, so I needed the URL too. Title was just for fun.

Here is the non ruby code to pull the variables that I needed out of the XML of the shared starred items in Google Reader.

XML=$(curl -s http://www.google.com/reader/public/atom/user/YOURUSERID/state/com.google/starred?n=1 | xmllint --format -)
OBJID=$(echo "$XML" | xpath "//entry/id" 2>/dev/null | awk -F"[<>]" '{print $3}')
TITLE=$(echo "$XML" | xpath "//entry/title" 2>/dev/null | awk -F"[<>]" '{print $3}')
URL=$(echo "$XML" | xpath "//entry/link/@href" 2>/dev/null | sed 's/\"//g' | sed 's/href\=//g' | sed 's/\ //g')
SOURCE=$(echo "$XML" | xpath "//entry/source/@gr:stream-id" 2>/dev/null | sed "s/gr:stream-id=//g" | sed "s/\"//g" | sed 's/\ //g')

After getting those variables, I wanted to put the URL in together.app (this has not changed since the previous post). Here is that code:

echo "Adding $TITLE to Together"
osascript << EOT
tell application "Together" to import url "$URL" as web PDF
EOT

How to add custom JavaScript code to all SharePoint 2010 pages (CustomAction)

There are plenty or articles on how to do this. This is more of a note for myself, as I have to “re-learn” this every time I need to customize SharePoint. There are 2 ways (that I know of) that you can add code to every page in SharePoint 2010, 1 by the AdditionalPageHead delegate control, or ,2 by Custom Action. This article is about #2 using a Custom Action. This article is about #1 – Delegate Controls

To add JavaScript to every page via CustomAction:

  1. Start Visual Studio, and create a new Empty SharePoint Project (uncheck the Create Directory for Solution because you salways create the destination directory yourself)
  2. Deploy as a Farm Solution (I have not figured what you can and can’t do with sandboxed solutions yet)
  3. RightCLick the Project and select Add Module and name the Module at the bottom (I name the Module the name of the Document Library where I want to put the file)
  4. Delete Sample.txt and add the javascript file you want (I usually have to go to the correct folder, put the file there, right click the ProjectName and select “Show all files”, then I can include the file in the project).
  5. Chop up the elements.xml file. The final should look like this below:
    1. is changed to (Url is the Doc Library where the file will be added)
    2. is changed to (Remove the path from Url and add the “GhostableInLibrary” part)
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="Test" Url="Test">
    <File Path="Test\jquery-1.7.min.js" Url="jquery-1.7.min.js" Type="GhostableInLibrary" />
  </Module>
</Elements>

Now you need to the code to add the file to the top of every page, add the “CustomAction” stuff below

  <CustomAction
    ScriptSrc="~SiteCollection/Test/jquery-1.7.min.js"
    Location="ScriptLink"
    Sequence="11">
  </CustomAction>

Final looks like this:

Right click the project and package it up.

Common PowerShell commands to work with solutions are (you must create the destination Document Library before you try to install this code):

To add/install
Add-SPSolution H:\Path\To\wsp\Test.wsp
Install-SPSolution Test.wsp -GACDeploy
Update-SPSolution -literalpath  H:\Path\To\wsp\Test.wsp -identity Test.wsp -GACDeploy

To remove
Uninstall-SPSolution Test.wsp
Remove-SPSolution Test.wsp

This results in a new Feature in manage features (Active it!)

A new file in the document library, and the following in the source code for the page. Done!:

Start Visual Studio form PowerShell

I am moving on to a new project – our migration from SharePoint 2007 to 2010. First thing I wanted to do was to upgrade my Solutions/Features from 2007 to 2010. I installed Visual Studio and started looking at how to recreate my Delegate JQuery Control (more on that later). The first thing I found annoying was that every time I added an “Empty SharePoint Project”, I received a warning “This task requires the application to have elevated permissions”. That is annoying. Since I usually leave a PowerShell prompt running as administrator (It has a red background to distinguish it), I wanted to quickly open VisualStudio from that PowerShell prompt. Here is my wrapper script to open VisualStudio 2010 from PowerShell:

function JBMURPHY-Start-VisualStudio {
Start-Process "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe" -workingdirectory "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\"
}

Deploy Visual Studio 2010 vai SCCM (silently)

I wanted to have Visual Studio 2010 on my machine. My motto is that if I have to install it, I should package it up in SCCM, so when I re-image, I can just press a button. Here were my steps. Nothing ground breaking in this post, but I wanted to document it for my self (and anyone else that could use it). Also, I am only documenting the steps that I feel are important, so maybe this will be a quick reference for someone.

First I needed to create an answer file: D:\setup\setup.exe /createunattend c:\VS2010_deployment.ini This will walk you through the install and save the settings to an ini file.

Second I added Visual Studio 2010 to SCCM via “new Package from definition” and changed the command line to Setup\setup.exe /UnattendFile \\SCCMServer\smspkgc$\PackageID\Setup\VS2010_deployment.ini

Third I changed the advertisement to “Run program from distribution point”

That was about it. Pretty easy.

Error: Request for the permission of type System.Web.AspNetHostingPermission failed

Every so often I have to go into some historical code to try and see what is happening. And every time I make the same mistake, I try to debug the code off my mapped user drive (I do everything in my user drive which is on a network share. And every time, I get the same error:

Security Exception
Description: The application attempted to perform an operation not allowed by the security policy.  To grant this application the required permission please contact your system administrator or change the application's trust level in the configuration file.

Exception Details: System.Security.SecurityException: Request for the permission of type 'System.Web.AspNetHostingPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.

Note to self, don’t debug from a local drive!