ColdFusionを使ったGoogle Baseのサンプルを自分流に改造する

元記事はこちらです。

■Application.cfm

<cfprocessingdirective pageEncoding = "UTF-8">
<cfsetting enableCFoutputOnly="no">

<cfapplication name="#hash( getCurrentTemplatePath() )#"
    sessionmanagement="yes"
    sessiontimeout=#CreateTimeSpan(1, 0, 0, 0)# >

<cfset request.url = thisURL()>

<cfset request.proxyServer  = "">
<cfset request.proxyPort    = "80">
<cfset request.g_key = "xxx">
<!---==========================================
    thisURL
        実行されたURL。ただしファイル名は削除。
        例)http://hoge.com/
===========================================--->
<cffunction name="thisURL" access="public" returnType="string" output="no">
    <cfset var local = structNew()>

    <cfset local.server_name = cgi.server_name>
    <cfif cgi.server_port neq 80>
        <cfset local.server_name = local.server_name & ":" & cgi.server_port>
    </cfif>

    <cfset local.url = "#lcase(ListFirst(cgi.server_protocol,"/"))#://#local.server_name##cgi.script_name#">
    <cfset local.url = ListDeleteAt(local.url, ListLen(local.url, "/"), "/") & "/">

    <cfreturn local.url>
</cffunction>

■index.cfm

<cfprocessingdirective pageEncoding = "UTF-8">
<cfparam name="url.p"       default="">
<cfparam name="url.token"   default="">
<cfparam name="url.page"    default="0">

<!--- session.gbase --->
<cfif ((not isDefined("session.gbase")) or (url.p eq "0"))>
    <cfset session.gbase = CreateObject("component", "gbase").init(
                                request.proxyServer,
                                request.proxyPort,
                                request.g_key)>
</cfif>

<!--- token set --->
<cfif (session.gbase.getGToken() eq "")>
    <cfif (url.token neq "")>
        <cfset session.gbase.setGToken(url.token)>

        <cfset cfhttp = session.gbase.AuthSubSessionToken()>
        <cfset token = ListLast(cfhttp.filecontent, "=")>
        <cfset session.gbase.setGToken(token)>
    </cfif>
</cfif>

<!--- 処理 --->
<cfset content = "">
<cfswitch expression = "#url.p#">
    <!--- 検索 --->
    <cfcase value="srch">
        <cfset qStr = cst_chkSrch(url.page)>
        <cfset cfhttp = session.gbase.gSrch(qStr)>
        <cfset resultsList = xmlparse(cfhttp.filecontent)>

        <!--- 検索画面表示 --->
        <cfset content = dsp_srch()>
        <!--- 一覧表示 --->
        <cfset content = content & dsp_list(resultsList)>
    </cfcase>

    <!--- カレンダーにセット --->
    <cfcase value="addToCal">
        <cfset data = cst_makeDataAddToCal()>
        <cfset cfhttp = session.gbase.sendTheEntryToGoogleCalendar(data)>

        <cfif ((left(cfhttp.statusCode,3) EQ "302"))>   <!--- If Google Calendar gives us a redirect, redirect --->
         <cfset redir=#cfhttp.responseHeader["location"]#>                  <!--- Get redirect location --->
         <cfhttp url="#redir#" method="post" redirect="no"
                proxyServer ="#request.proxyServer#"
                proxyPort   ="#request.proxyPort#"

         >                  <!--- Send the old entry to the new location --->
              <cfhttpparam type="header" name="Content-Type" value="application/atom+xml"> 
              <cfhttpparam type="header" name="Authorization" value="AuthSub token=#session.gbase.getGToken()#">
              <cfhttpparam type="Body" value="#data#">
         </cfhttp>

         <center>
         <font size=+2 color="##4466DD" face="verdana"><b>CalendarMeIn</b></font><br>
        Google Base/Google Calendar Event Scheduler <font color="##787878">BETA</font>
         <br><br><br><br>The event "#title#" has been added to your calendar!<br><br>
         <a href="http://calendar.google.com">View Calendar</a> <br> <a href="eventscheduler.cfm?token=#token#&search=1">Back to Event Search</a>
        </center><br><br>
                                                                            <!--- If Calendar returns a "500", "404" or "400" code, we have a problem... --->
        <cfelseif ((left(cfhttp.statusCode,3) EQ "500") or (left(cfhttp.statusCode,3) EQ "400") or (left(cfhttp.statusCode,3) EQ "404"))>
         <b><font size=+1>Unable to add event to Google Calendar. Please make sure you have a Google Calendar account set up and that you are logged into it. Please visit <a href="http://calendar.google.com" target="_blank">calendar.google.com</a> to sign up, then refresh this page to try again.</font></b>
        <cfelse>
        Error - status:<br>
        #cfhttp.header# 
        </cfif>

    </cfcase>

    <!--- 指定処理以外 --->
    <cfdefaultcase>
        <cfif (session.gbase.getGToken() eq "")>
            <!--- 初期画面表示 --->
            <cfset content = dsp_init()>
        <cfelse>
            <!--- 検索画面表示 --->
            <cfset content = dsp_srch()>
        </cfif>
    </cfdefaultcase>
</cfswitch>
<cfoutput>#content#</cfoutput>
<!---===============================
dsp_init
    初期画面
================================--->
<cffunction name="dsp_init" access="public" returnType="string" output="no">
    <cfset var ret = "">

    <cfsavecontent variable = "ret">
    <cfoutput>
    Please <a href="https://www.google.com/accounts/AuthSubRequest?next=#request.url#index.cfm&p=aa&scope=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F&session=1&secure=0">click here</A> to authorize.<br>
    </cfoutput>
    </cfsavecontent>

    <cfreturn ret>
</cffunction>
<!---===============================
dsp_srch
================================--->
<cffunction name="dsp_srch" access="public" returnType="string" output="no">
    <cfset var ret = "">

    <cfsavecontent variable = "ret">
    <cfoutput>
    <FORM name="gbsearch" action="index.cfm?p=srch" method="post">  <!--- Submits the query to this same form, getting the Base results --->
    <table border="0" cellspacing="6" cellPadding="0" align=center>
    <tr>
        <td rowspan="3" valign="top" width=200>&nbsp;</td>
        <td rowspan="3">&nbsp;&nbsp;</td>
        <td style="font-size:80%">
            Event Type: <br><select name="eventType">
             <option value="">All</option>
             <option value="Art ">- Art</option>
             <option value="Class OR Lesson OR Lecture">- Classes and Lectures</option>
             <option value="Comedy OR Stand-up OR Standup ">- Comedy</option>
             <option value="Food OR Cuisine ">- Food</option>
             <option value="Festival OR Fair ">- Festivals and Fairs</option>
             <option value="Music OR Concert ">- Music</option>
             <option value="Reading OR Signing ">- Readings and Signings</option>
             <option value="Shopping OR Sale OR Market ">- Shopping</option>
            </select> or other: <INPUT name="textQuery" type="text" size="20" > &nbsp; &nbsp; <button type="submit" >Search for events</BUTTON>
        </td>
    </tr>

    <tr>
        <td style="font-size:80%">
        Location:<br> <select name="miles">
         <option value="5">Within 5 miles</option>
         <option value="10">Within 10 miles</option>
         <option value="25">Within 25 miles</option>
         <option value="50">Within 50 miles</option>
        </select> of &nbsp; <input name="location" type="text" size="20" ><font color="##222222"> (leave blank for anywhere)</font>
        </td>
    </tr>   
        
    <tr>
        <td style="font-size:80%">
       
       When:<br><select name="dateMonth">
        <option value="00">Any</option>
        <option value="01">January</option>
        <option value="02">February</option>
        <option value="03">March</option>
        <option value="04">April</option>
        <option value="05">May</option>
        <option value="06">June</option>
        <option value="07">July</option>
        <option value="08">August</option>
        <option value="09">September</option>
        <option value="10">October</option>
        <option value="11">November</option>
        <option value="12">December</option>
       </select>
      
       <select name="dateDay">
        <option value="00">Any</option>
        <option value="01">1</option>
        <option value="02">2</option>
        <option value="03">3</option>
        <option value="04">4</option>
        <option value="05">5</option>
        <option value="06">6</option>
        <option value="07">7</option>
        <option value="08">8</option>
        <option value="09">9</option>
        <option value="10">10</option>
        <option value="11">11</option>
        <option value="12">12</option>
        <option value="13">13</option>
        <option value="14">14</option>
        <option value="15">15</option>
        <option value="16">16</option>
        <option value="17">17</option>
        <option value="18">18</option>
        <option value="19">19</option>
        <option value="20">20</option>
        <option value="21">21</option>
        <option value="22">22</option>
        <option value="23">23</option>
        <option value="24">24</option>
        <option value="25">25</option>
        <option value="26">26</option>
        <option value="27">27</option>
        <option value="28">28</option>
        <option value="29">29</option>
        <option value="30">30</option>
        <option value="31">31</option>
       </select>
       
       <select name="dateYr">
        <option value="2006">2006</option>   
        <option value="2007">2007</option>
        <option value="2008">2008</option>
        <option value="2009">2009</option>
        <option value="2010">2010</option>
       </select>
      
    </td>
    </tr>
    </table>
    </FORM>
  
    </cfoutput>
    </cfsavecontent>

    <cfreturn ret>
</cffunction>
<!---===============================
dsp_list
================================--->
<cffunction name="dsp_list" access="public" returnType="string" output="no">
    <cfargument name="xmlData" type="xml" required="yes">

    <cfset var ret = "">
    <cfset var resultsList = arguments.xmlData>

    <cfsavecontent variable = "ret">
    <cfoutput>
    <cfif isdefined("resultsList.feed.entry")>                                          <!--- If there are results, display them --->
        <div style='padding:0px; width: 72%;background-color:##555555;'>

        <cfloop index="loopIndex" from="1" to="#arraylen(resultsList.feed.entry)#">
            <cfset currentResult = resultsList.feed.entry[loopIndex]>                           <!--- Store the current product in a temporary variable --->

            <cfset addEventURL="#request.url#?p=addtocal&title=#urlencodedformat(currentResult.title.xmltext)#">

            <cfif isdefined("currentResult.location")>                                      <!--- If there's a location, add it to the query --->
                <cfset addEventURL=(addEventURL & "&where=#urlencodedformat(currentResult.location.xmltext)#")>
            </cfif>

            <cfif isdefined("currentResult.event_date_range")>                                  <!--- If there's a date, add it to the query and format the dates for display --->
                <cfset addEventURL=(addEventURL & "&when=#urlencodedformat(currentResult.event_date_range.xmltext)#")>
                <cfset startdate=trim(mid(currentResult.event_date_range.xmltext, 1, find(" ", currentResult.event_date_range.xmltext)))>
                <cfset enddate=trim(mid(currentResult.event_date_range.xmltext, find(" ", currentResult.event_date_range.xmltext) + 1, len(currentResult.event_date_range.xmltext)))>
                <cfif startdate EQ "">
                    <cfset startdate = enddate>
                </cfif>
            </cfif>

            <cfif isdefined("currentResult.link")>                                              <!--- If there's a link, add it to the query --->
                <cfset addEventURL=(addEventURL & "&link=#urlencodedformat(currentResult.link.xmlattributes.href)#")>
            </cfif>

            <div style='padding:3px;border:1px solid darkblue;background-color:##AABBFF;text-align:left;position: relative;top: -5px;left: -3px;'><b> &nbsp; #currentResult.title.xmltext#</b></div>
            <div style='background-color:##F1F1FF;border:1px solid gray;position: relative;top:-1px;left:-1px;'>
            <table width="98%" cellpadding="2" cellspacing="2"><tr><td><font size=-1>

            <b>Link:</b> <a href="#currentResult.link.xmlattributes.href#">#currentResult.link.xmlattributes.href#</a><br>

            <cfif isdefined("currentResult.location")>                                          <!--- If there's a location, display it --->
                <b>Where:</b> <a href="http://maps.google.com/maps?f=q&hl=en&q=#urlencodedformat(currentResult.location.xmltext)#">#currentResult.location.xmltext#</a><br>
            </cfif>  

            <cfif isdefined("currentResult.event_date_range")>                                  <!--- If there are dates, format and display them --->
                <cfif startdate NEQ enddate>
                    <cfset startyear=mid(startdate, 1, 4)>
                    <cfset startmonth=mid(startdate, 6, 2)>
                    <cfset startday=mid(startdate, 9, 2)>
                    <cfset starttime=mid(startdate, 12,5)>
                    <cfset endyear=mid(enddate, 1, 4)>
                    <cfset endmonth=mid(enddate, 6, 2)>
                    <cfset endday=mid(enddate, 9, 2)>
                    <cfset endtime=mid(enddate, 12,5)>
                    <b>When:</b> #startmonth#/#startday#/#startyear# #starttime# - #endmonth#/#endday#/#endyear# #endtime#<br><br>
                <cfelse>
                    <cfset startyear=mid(startdate, 1, 4)>
                    <cfset startmonth=mid(startdate, 6, 2)>
                    <cfset startday=mid(startdate, 9, 2)>
                    <b>When:</b> #startmonth#/#startday#/#startyear#<br><br>
                </cfif>
            </cfif>

            <cfif #currentResult.content.xmltext# EQ "">                                        <!--- If there is a value in the description, display it --->
                <b>Description:</b> (no description given)
            <cfelse>
                <b>Description:</b> #currentResult.content.xmltext#
            </cfif>

            </font><br><br></td><td rowspan="2" width="5%">
            <center><a href="#addEventURL#"><img src="calendar.jpeg" alt="Add to calendar" border="0" align="center"><br><font size="-2" face="verdana">Add To<br>Calendar</font></a></center>
            </td></tr></table>
            </div>
        </cfloop>
        </div>
    </cfif>
    </cfoutput>
    </cfsavecontent>

    <cfreturn ret>
</cffunction>
<!---===============================
cst_chkSrch
================================--->
<cffunction name="cst_chkSrch" access="public" returnType="string" output="no">
    <cfargument name="page"     type="string" required="yes">
    <cfargument name="maxRow"   type="string" default="15">

    <cfset var local = structNew()>

    <cfset local.start = 1 + arguments.page * arguments.maxRow>

    <!--- Initial query string setup --->
    <cfset local.queryString="http://www.google.com/base/feeds/snippets?start-index=#local.start#&max-results=#arguments.maxRow#&bq=">

    <cfif isdefined("form.location")>                                               <!--- If this field is present, then we have an actual search query --->
        <cfif isdefined("form.textQuery")>                                                      <!--- If the user wants to refine by text, add it --->
            <cfset local.querystring = local.queryString & form.eventType & form.textQuery & " ">
        </cfif>

        <cfset local.queryString = local.queryString & "[item type:events and activities] ">                <!--- Restrict items to events --->

        <cfif form.location NEQ "">                                                             <!--- If location actually has a value, add it --->
            <cfset local.queryString = local.queryString & "%5Blocation%3A%40%22#form.location#%22%2B#miles#mi%5D">
        </cfif>
                                                                                            <!--- Only return items AFTER today --->
        <cfset local.queryString = local.queryString & "[event_date_range > " & dateformat(now(), "YYYY-MM-DD") & "] ">

        <cfif (form.dateDay EQ "00") or (form.dateMonth EQ "00") or (form.dateYr EQ "0000")>                <!--- If user specified a date range, add that too --->
            <cfif (form.dateDay EQ "00") and (form.dateMonth EQ "00") and (form.dateYr EQ "0000")>
            No date specified!<br>
            <cfelseif (form.dateDay EQ "00") and (form.dateMonth EQ "00")>
                <cfset local.queryString = local.queryString & "[event_date_range: #form.dateYr#Z]">
            <cfelseif (form.dateDay EQ "00")>
                <cfset local.queryString = local.queryString & "[event_date_range: #form.dateYr#-#form.dateMonth#Z]">
            </cfif>
        <cfelse>
            <cfset local.queryString = local.queryString & "[event_date_range: #form.dateYr#-#form.dateMonth#-#form.dateDay#Z]">
        </cfif>
    </cfif>

    <cfreturn local.queryString>
</cffunction>
<!---===============================
cst_makeDataAddToCal
================================--->
<cffunction name="cst_makeDataAddToCal" access="public" returnType="string" output="no">

    <cfif isdefined("when")>                                            <!--- If there's a date... --->
        <cfset startdate=trim(mid(when, 1, find(" ", when)))>               <!--- Start date starts at the beginning, ends at the first space --->
        <cfset enddate=trim(mid(when, find(" ", when) + 1, len(when)))> <!--- End date is the rest of it --->
        <cfif startdate EQ "">                                          <!--- If the event JUST has a start date, startDate will be empty right now --->
            <cfif mid(enddate, 12, 8) EQ "00:00:00">                            <!--- If enddate has no time specified, chop it off --->
                <cfset enddate = mid(enddate, 1, 10)>
            </cfif>
            <cfset startdate = enddate>
        </cfif>
    </cfif>
                                                    <!--- Set up the initial Calendar XML entry --->
    <cfset xmlentry="<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gd='http://schemas.google.com/g/2005'> <category scheme='http://schemas.google.com/g/2005##kind' term='http://schemas.google.com/g/2005##event'></category> <title type='text'>#urldecode(title)#</title>">

    <cfif isdefined("link")>                                            <!--- If there's a link, add it to the entry --->
        <cfset xmlentry = xmlentry & "<content type='text'><![CDATA[#urldecode(link)#]]></content>">
    </cfif>

    <cfif isdefined("where")>                                           <!--- If there's a location, add it to the entry --->
        <cfset xmlentry = xmlentry & "<gd:where valueString='#urldecode(where)#'></gd:where>">
    </cfif>

    <cfif isdefined("when")>                                            <!--- If there's a time, add it to the entry --->
        <cfset xmlentry = xmlentry & "<gd:when startTime='#startdate#'">
        <cfif startDate NEQ endDate>                                    
            <cfset xmlentry = xmlentry & " endTime='#enddate#'">
        </cfif>
        <cfset xmlentry = xmlentry & "></gd:when>">
    </cfif>

    <cfset xmlentry = xmlentry & "</entry>">

    <cfreturn xmlentry>
</cffunction>

■gbase.cfc

<!---/////////////////////////////////////////////////////////////////
gbase
//////////////////////////////////////////////////////////////////--->
<cfcomponent>
    <cfset variables.proxyServer    = "">
    <cfset variables.proxyPort      = "">
    <cfset variables.g_key          = "">
    <cfset variables.token          = "">
<!---/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/
public
/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=/=--->
    <!---===============================
    init
    ================================--->
    <cffunction name="init" access="public" returnType="gbase" output="no">
        <cfargument name="proxyServer"  type="string" required="yes">
        <cfargument name="proxyPort"    type="string" required="yes">
        <cfargument name="g_key"        type="string" required="yes">

        <cfset variables.proxyServer    = arguments.proxyServer>
        <cfset variables.proxyPort      = arguments.proxyPort>
        <cfset variables.g_key          = arguments.g_key>

        <cfreturn this>
    </cffunction>

    <!---===============================
    AuthSubSessionToken
    ================================--->
    <cffunction name="AuthSubSessionToken" access="public" returnType="any" output="no">

        <cfhttp method="get" url="http://www.google.com/accounts/AuthSubSessionToken"
                proxyServer ="#variables.proxyServer#"
                proxyPort   ="#variables.proxyPort#"
        >
            <cfhttpparam type="header" name="Content-Type" value="application/atom+xml"> 
            <cfhttpparam type="header" name="Authorization" value="AuthSub token=#variables.token#">
            <cfhttpparam name="X-Google-Key" type="Header" value="key=#variables.g_key#">
        </cfhttp>
    
        <cfreturn cfhttp>
    </cffunction>

    <!---===============================
    sendTheEntryToGoogleCalendar
        Send the entry to Google Calendar
    ================================--->
    <cffunction name="sendTheEntryToGoogleCalendar" access="public" returnType="any" output="no">
        <cfargument name="xmlData"  type="string" required="yes">

        <cfhttp url="http://www.google.com/calendar/feeds/default/private/full" method="post" redirect="no"
            proxyServer ="#variables.proxyServer#"
            proxyPort   ="#variables.proxyPort#"
            >
            <cfhttpparam type="header" name="Content-Type" value="application/atom+xml"> 
            <cfhttpparam type="header" name="Authorization" value="AuthSub token=#variables.token#">
            <cfhttpparam type="Body" value="#arguments.xmlData#">
        </cfhttp>

        <cfreturn cfhttp>
    </cffunction>

    <!---===============================
    gSrch
    ================================--->
    <cffunction name="gSrch" access="public" returnType="any" output="no">
        <cfargument name="qStr" type="string" required="yes">

        <cfhttp method="Get" url="#arguments.qStr#"
            proxyServer ="#variables.proxyServer#"
            proxyPort   ="#variables.proxyPort#"
        >                                           <!--- Send out the query to Base --->
            <cfhttpparam name="X-Google-Key" type="Header" value="key=#variables.g_key#">
        </cfhttp>

        <cfreturn cfhttp>
    </cffunction>

    <!---===============================
    getter,setter
    ================================--->
    <!--- token --->
    <cffunction name="getGToken" access="public" returnType="string" output="no">
        <cfreturn variables.token>
    </cffunction>
    <cffunction name="setGToken" access="public" returnType="void" output="no">
        <cfargument name="token" type="string" required="yes">
    
        <cfset variables.token = arguments.token>
    </cffunction>
</cfcomponent>