Advertisement
Guest User

Untitled

a guest
Jul 13th, 2010
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!---
  2.     Name         : youtube.cfc (v2)
  3.     Author       : Raymond Camden
  4.     Created      : August 20, 2007
  5.     Last Updated : October 1, 2009
  6.     History      : Added getVideo, parseEntry support, getEmbedCode
  7.                    Added delete and update methods. (Update 21/05/08 by Roland Keijzer)
  8.                    See readme.txt for latest news.
  9. --->
  10.  
  11. <cfcomponent displayName="YouTube CFC" output="false">
  12.  
  13. <cfset variables.authtoken="">
  14. <cfset variables.username="">
  15. <cfset variables.devkey="">
  16.  
  17. <cfset variables.standardurl = "http://gdata.youtube.com/feeds/api/standardfeeds/">
  18.  
  19. <cffunction name="init" access="public" returnType="youtube" output="false">
  20.     <cfargument name="devkey" type="string" required="true">
  21.     <cfset variables.devkey = arguments.devkey>
  22.     <cfreturn this>
  23. </cffunction>
  24.  
  25. <cffunction name="addFavoriteVideoForUser" access="public" returntype="any" output="false" hint="Adds a Favorites Video of the user">
  26.     <cfargument name="videoId" type="string" required="true">
  27.     <cfset var theurl = "http://gdata.youtube.com/feeds/api/users/default/favorites">
  28.     <cfset var result = "">
  29.     <cfset var meta = "">
  30.    
  31. <cfsavecontent variable="meta">
  32. <cfoutput>
  33. <?xml version="1.0" encoding="UTF-8"?>
  34. <entry xmlns="http://www.w3.org/2005/Atom">
  35. <id>#arguments.videoid#</id>
  36. </entry>
  37. </cfoutput>
  38. </cfsavecontent>
  39.  
  40.     <cfset meta = trim(meta)>
  41.  
  42.     <cfhttp url="#theurl#" method="post" result="result">
  43.         <cfhttpparam type="header" name="Host" value="gdata.youtube.com">  
  44.         <cfhttpparam type="header" name="Content-Type" value="application/atom+xml">
  45.         <cfhttpparam type="header" name="Content-Length" value="#len(meta)#">
  46.         <cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#variables.authtoken#">
  47.         <cfhttpparam type="header" name="X-GData-Client" value="youtubecfc">
  48.         <cfhttpparam type="header" name="X-GData-Key" value="key=#variables.devkey#">
  49.         <cfhttpparam type="header" name="GData-Version" value="2">
  50.         <cfhttpparam type="body" value="#meta#">
  51.     </cfhttp>
  52. </cffunction>  
  53.  
  54. <!--- Note - this method was begun but ran into issues. Leaving it out for now.
  55. <cffunction name="addPlaylist" access="public" returntype="any" output="false"  hint="Adds a playlist for a user.">
  56.     <cfargument name="title" type="string" required="true">
  57.     <cfargument name="description" type="string" required="true">
  58.  
  59.     <cfset var theurl = "http://gdata.youtube.com/feeds/api/users/default/playlists">
  60.     <cfset var result = "">
  61.     <cfset var meta = "">
  62.     <cfset var tmpFile = expandPath("./#replace(createUUID(),'-','_','all')#")>
  63.     <cfset var resxml = "">
  64.  
  65. <cfsavecontent variable="meta">
  66. <cfoutput>
  67. <?xml version="1.0" encoding="UTF-8"?>
  68. <entry xmlns="http://www.w3.org/2005/Atom" xmlns:yt="http://gdata.youtube.com/schemas/2007">
  69. <title type="text">#xmlFormat(arguments.title)#</title>
  70. <summary>#XMLFormat(arguments.description)#</summary>
  71. </entry>
  72. </cfoutput>
  73. </cfsavecontent>
  74.  
  75.     <cfset meta = trim(meta)>
  76.     <cffile action="write" file="#tmpfile#" output="#meta#">
  77.  
  78.     <cfhttp url="#theurl#" method="post" result="result">
  79.         <cfhttpparam type="header" name="Host" value="gdata.youtube.com">  
  80.         <cfhttpparam type="header" name="Content-Type" value="application/atom+xml">
  81.         <cfhttpparam type="header" name="Content-Length" value="#len(meta)#">
  82.         <cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#variables.authtoken#">    
  83.         <cfhttpparam type="header" name="X-GData-Client" value="youtubecfc">
  84.         <cfhttpparam type="header" name="X-GData-Key" value="key=#variables.devkey#">
  85.         <cfhttpparam type="file" name="API_XML_Request" file="#tmpfile#" mimetype="application/atom+xml; charset=UTF-8 ">      
  86.     </cfhttp>
  87.     <cffile action="delete" file="#tmpfile#">
  88. </cfoutput>
  89. <cfdump var="#result#"><cfabort>
  90. </cffunction>
  91. --->
  92.  
  93. <cffunction name="delete" access="public" returnType="any" output="false" hint="I update a video.">
  94.     <cfargument name="videoId" type="string" required="true">
  95.    
  96.     <cfset var theurl = "http://uploads.gdata.youtube.com/feeds/api/users/#variables.username#/uploads/">
  97.     <cfset var result = "">
  98.     <cfset var resxml = "">
  99.  
  100.     <!--- Video ID may include the URL, strip it --->
  101.     <cfset arguments.videoid = replace(arguments.videoid, "http://gdata.youtube.com/feeds/api/videos/","")>
  102.     <cfset arguments.videoid = listFirst(arguments.videoid, "&")>  
  103.  
  104.     <cfset theurl &=  arguments.videoId />
  105.    
  106.     <cfhttp url="#theurl#" method="delete" result="result">
  107.         <cfhttpparam type="header" name="Host" value="gdata.youtube.com">
  108.         <cfhttpparam type="header" name="Content-Type" value="application/atom+xml">
  109.         <cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#variables.authtoken#">
  110.         <cfhttpparam type="header" name="X-GData-Client" value="youtubecfc">
  111.         <cfhttpparam type="header" name="X-GData-Key" value="key=#variables.devkey#">
  112.     </cfhttp>
  113.     <cfif result.responseheader.explanation is "OK">
  114.         <cfreturn "Video successfully removed.">
  115.     <cfelse>
  116.         <cfif isXml(result.filecontent)>
  117.             <cfset resxml = xmlParse(result.fileContent)>
  118.             <cfthrow message="YouTubeCFC Upload Error: Domain=#resxml.errors.error.domain.xmlText#, Code=#resxml.errors.error.code.xmlText#">
  119.         <cfelse>
  120.             <cfthrow message="YouTubeCFC Upload Error: Status: #result.responseheader.status_code# / Explanation: #result.responseheader.explanation#">
  121.         </cfif>
  122.     </cfif>
  123. </cffunction>  
  124.  
  125. <cffunction name="deleteFavoriteVideoForUser" access="public" returntype="any" output="false" hint="Deletes a Favorites Video of the user">
  126.     <cfargument name="videoId" type="string" required="true">
  127.     <cfset var theurl = "http://gdata.youtube.com/feeds/api/users/#variables.username#/favorites/#arguments.videoid#">
  128.     <cfset var result = "">
  129.  
  130.     <cfhttp url="#theurl#" method="delete" result="result">
  131.         <cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#variables.authtoken#">
  132.         <cfhttpparam type="header" name="X-GData-Client" value="youtubecfc">
  133.         <cfhttpparam type="header" name="X-GData-Key" value="key=#variables.devkey#">
  134.     </cfhttp>
  135.  
  136. </cffunction>  
  137.  
  138. <!---
  139. YT has some FUNKY rules for the keyword string you sent them. Much too funky for the average user. This function
  140. was built to help correct user input so that YT will be happy. From their docs:
  141.  
  142. The <media:keywords> tag contains a comma-separated list of words associated with a video. You must provide at least one keyword for
  143. each video in your feed. This field has a maximum length of 120 characters, including commas, and may contain all valid
  144. UTF-8 characters except < and <. In addition, each keyword must be at least two characters long and may not be longer than 25 characters.
  145.  
  146. Please note that individual keywords may not contain spaces. However, you can use spaces after the commas that separate keywords.
  147. For example, crazy,surfing,stunts and crazy, surfing, stunts are both valid values for this tag. However, crazy, surfing stunts
  148. is not valid. (The invalid value does not contain a comma between "surfing" and "stunts".)
  149. --->
  150. <cffunction name="fixKeywords" access="private" returnType="string" output="false">
  151.     <cfargument name="s" type="string" required="true">
  152.    
  153.     <!--- split by words --->
  154.     <cfset var words = reMatch("[[:word:]]+", arguments.s)>
  155.     <cfset var result = "">
  156.     <cfset var w = "">
  157.        
  158.     <cfloop index="w" array="#words#">
  159.         <cfif len(w) gte 2>
  160.             <cfif len(w) gt 25>
  161.                 <cfset w = left(w,25)>
  162.             </cfif>
  163.         </cfif>
  164.         <!--- only add if we won't go over 120 --->
  165.         <cfif len(listAppend(result,w)) gt 120>
  166.             <!--- leave now! --->
  167.             <cfreturn result>
  168.         </cfif>
  169.         <cfset result = listAppend(result,w)>
  170.     </cfloop>
  171.  
  172.     <cfreturn result>
  173.     <!---
  174.     This was attempt 1, which I got rid of - but I'm keeping the code for now.
  175.     <!--- first reduce to 120 chars --->
  176.     <cfset arguments.s = left(arguments.s, 120)>
  177.     <!--- remove < and > --->
  178.     <cfset arguments.s = rereplace(arguments.s, "[<>]", "", "all")>
  179.     <!--- get words, if < 2 chars, remove it, if more > 25, trim it --->
  180.     <cfset arguments.s = rereplace(arguments.s, "\w{", "\1, \2", "all")>
  181.  
  182.     <!--- replace any (noncomma)(space)(noncomma) with (noncomma),(space)(noncomma) --->
  183.     <cfset arguments.s = rereplace(arguments.s, "([[:alnum:]])[[:space:]]+([[:alnum:]])", "\1, \2", "all")>
  184.     <cfreturn arguments.s>
  185.     --->
  186. </cffunction>
  187.  
  188. <cffunction name="getCategories" access="public" returnType="array" output="false"
  189.             hint="Gets the valid categories for YouTube.">
  190.     <cfset var curl = "http://gdata.youtube.com/schemas/2007/categories.cat">
  191.     <cfset var results = arrayNew(1)>
  192.     <cfset var result = "">
  193.     <cfset var x = "">
  194.    
  195.     <cfhttp url="#curl#" result="result">
  196.     <cfset result = xmlparse(result.filecontent)>
  197.     <!--- Note, we use just the term, not the label. --->
  198.     <cfloop index="x" from="1" to="#arrayLen(result["app:categories"]["atom:category"])#">
  199.         <cfset arrayAppend(results, result["app:categories"]["atom:category"][x].xmlAttributes.term)>
  200.     </cfloop>
  201.  
  202.     <cfreturn results>
  203. </cffunction>
  204.  
  205. <cffunction name="getChannels" access="public" returntype="query" output="false" hint="Gets Channels List by search.">
  206.     <cfargument name="search" type="string" required="true">
  207.     <cfargument name="start" type="numeric" required="false">
  208.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  209.     <cfargument name="strict" type="string" required="false" default="true" hint="Instruct API to ignore Invalid requests">
  210.  
  211.     <cfset var baseurl = "http://gdata.youtube.com/feeds/api/channels">
  212.     <cfset var result = "">
  213.     <cfset var results = queryNew("id,updated,title,summary,url,videocount,link,author,authorurl,total")>
  214.     <cfset var x = "">
  215.     <cfset var total = "">
  216.     <cfset var entry = "">
  217.    
  218.     <cfset baseurl &= "?v=2&q=#urlEncodedFormat(arguments.search)#">
  219.  
  220.     <cfif structKeyExists(arguments, "start")>
  221.         <cfset baseurl &= "&start-index=#arguments.start#">
  222.     </cfif>
  223.     <cfif structKeyExists(arguments, "max")>
  224.         <cfset baseurl &= "&max-results=#arguments.max#">
  225.     </cfif>
  226.     <cfif structKeyExists(arguments, "strict")>
  227.         <cfset baseurl &= "&strict=#arguments.strict#">
  228.     </cfif>
  229.  
  230.     <cfhttp url="#baseurl#" result="result">
  231.     <cfset result = xmlParse(result.filecontent)>
  232.  
  233.     <cfif not structKeyExists(result, "feed") or not structKeyExists(result.feed, "entry") or arrayLen(result.feed.entry) is 0>
  234.         <cfreturn results>
  235.     </cfif>
  236.    
  237.     <cfset total = result.feed["openSearch:totalResults"].xmlText>
  238.  
  239.     <cfloop index="x" from="1" to="#arrayLen(result.feed.entry)#">
  240.         <cfset entry = result.feed.entry[x]>
  241.         <cfset queryAddRow(results)>
  242.         <cfset querySetCell(results, "id", entry.id.xmlText)>
  243.         <cfset querySetCell(results, "updated", handleDate(entry.updated.xmlText))>
  244.         <cfset querySetCell(results, "title", entry.title.xmlText)>
  245.         <cfset querySetCell(results, "summary", entry.summary.xmlText)>
  246.         <cfset querySetCell(results, "url", entry["gd:feedLink"].xmlAttributes.href)>
  247.         <cfset querySetCell(results, "videocount", entry["gd:feedLink"].xmlAttributes.countHint)>
  248.         <cfset querySetCell(results, "link", entry.link[2].xmlattributes.href)>
  249.         <cfset querySetCell(results, "author", entry.author.name.xmlText)>
  250.         <cfset querySetCell(results, "authorurl", entry.author.uri.xmlText)>
  251.         <cfset querySetCell(results, "total", total)>      
  252.     </cfloop>
  253.     <cfreturn results>
  254. </cffunction>
  255.  
  256. <cffunction name="getComments" access="public" returnType="query" output="false"
  257.             hint="Gets all the comments for a video.">
  258.     <cfargument name="videoid" type="string" required="true">
  259.     <cfset var commentsurl = "http://gdata.youtube.com/feeds/api/videos/#arguments.videoid#/comments">
  260.     <cfset var result = "">
  261.     <cfset var comments = queryNew("total,published,title,content,author,authorurl")>
  262.     <cfset var total = "">
  263.     <cfset var x = "">
  264.     <cfset var comment = "">
  265.    
  266.  
  267.     <cfhttp url="#commentsurl#" result="result">
  268.     <cfif not isXml(result.fileContent)>
  269.         <cfthrow message="#result.fileContent#">
  270.     </cfif>
  271.     <cfset result = xmlParse(result.fileContent)>
  272.    
  273.     <cfset total = result.feed["openSearch:totalResults"].xmlText>
  274.    
  275.     <cfif not total>
  276.         <cfreturn comments>
  277.     </cfif>
  278.    
  279.     <cfloop index="x" from="1" to="#arrayLen(result.feed["entry"])#">
  280.         <cfset comment = result.feed["entry"][x]>
  281.         <cfset queryAddRow(comments)>
  282.         <cfset querySetCell(comments, "total", total)>
  283.         <cfset querySetCell(comments, "published", handleDate(comment.published.xmltext))>
  284.         <cfset querySetCell(comments, "title", comment.title.xmltext)>
  285.         <cfset querySetCell(comments, "content", comment.content.xmltext)>
  286.         <cfset querySetCell(comments, "author", comment.author.name.xmltext)>
  287.         <cfset querySetCell(comments, "authorurl", comment.author.uri.xmltext)>
  288.     </cfloop>
  289.  
  290.     <cfreturn comments>
  291. </cffunction>
  292.  
  293. <cffunction name="getEmbedCode" access="public" returnType="string" output="false" hint="Utility function to return embed html">
  294.     <cfargument name="videoid" type="string" required="true">
  295.     <!--- Video ID may include the URL, strip it --->
  296.     <cfset arguments.videoid = replace(arguments.videoid, "http://gdata.youtube.com/feeds/api/videos/","")>
  297.     <cfset arguments.videoid = listFirst(arguments.videoid, "&")>  
  298.     <cfreturn '<object width="425" height="355"><param name="movie" value="http://www.youtube.com/v/#arguments.videoid#&hl=en"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/#arguments.videoid#&hl=en" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"></embed></object>'>
  299. </cffunction>
  300.  
  301. <cffunction name="getFavoriteVideosForUser" access="public" returntype="any" output="false" hint="Get Favorites Video of the user">
  302.     <cfset var theurl = "http://gdata.youtube.com/feeds/api/users/default/favorites">
  303.     <cfreturn getVideos(myurl=theurl,secure=true)>
  304. </cffunction>
  305.    
  306. <cffunction name="getPlaylist" access="public" returnType="query" output="false"
  307.             hint="Gets a playlist.">
  308.     <cfargument name="plurl" type="string" required="true">
  309.     <cfargument name="start" type="numeric" required="false" default="1">
  310.     <cfargument name="max" type="numeric" required="false" default="50">
  311.  
  312.     <cfif not find("?", arguments.plurl)>
  313.         <cfset arguments.plurl &= "?">
  314.     </cfif>
  315.    
  316.     <cfif structKeyExists(arguments, "start")>
  317.         <cfset arguments.plurl &= "&start-index=#arguments.start#">
  318.     </cfif>
  319.     <cfif structKeyExists(arguments, "max")>
  320.         <cfset arguments.plurl &= "&max-results=#arguments.max#">
  321.     </cfif>
  322.     <cfreturn getVideos(arguments.plurl)>
  323. </cffunction>
  324.  
  325. <cffunction name="getPlaylists" access="public" returnType="query" output="false"
  326.             hint="Gets playlists for a user.">
  327.     <cfargument name="user" type="string" required="true">
  328.     <cfargument name="startindex" type="numeric" required="true" default="1">
  329.     <cfargument name="max" type="numeric" required="true" default="25">
  330.  
  331.     <cfset var baseurl = "http://gdata.youtube.com/feeds/api/users/#arguments.user#/playlists">
  332.     <cfset var result = "">
  333.     <cfset var results = queryNew("total,url,published,updated,title,content,author,authorurl,videocount,playlistid")>
  334.     <cfset var x = "">
  335.     <cfset var total = "">
  336.     <cfset var entry = "">
  337.  
  338.     <cfset baseurl &= "?start-index=#arguments.startindex#&max-results=#arguments.max#">
  339.    
  340.     <cfhttp url="#baseurl#" result="result">
  341.     <cfset result = xmlParse(result.filecontent)>
  342.     <cfif not structKeyExists(result.feed, "entry")>
  343.         <cfreturn results>
  344.     </cfif>
  345.  
  346.     <cfset total = result.feed["openSearch:totalResults"].xmlText>
  347.        
  348.     <cfloop index="x" from="1" to="#arrayLen(result.feed.entry)#">
  349.         <cfset entry = result.feed.entry[x]>
  350.         <cfset queryAddRow(results)>
  351.         <cfset querySetCell(results, "total", total)>
  352.         <cfset querySetCell(results, "url", entry["gd:feedLink"].xmlAttributes.href)>
  353.         <cfset querySetCell(results, "published", handleDate(entry.published.xmlText))>
  354.         <cfset querySetCell(results, "updated", handleDate(entry.updated.xmlText))>
  355.         <cfset querySetCell(results, "title", entry.title.xmlText)>
  356.         <cfset querySetCell(results, "content", entry.content.xmlText)>
  357.         <cfset querySetCell(results, "author", entry.author.name.xmlText)>
  358.         <cfset querySetCell(results, "authorurl", entry.author.uri.xmlText)>
  359.         <cfset querySetCell(results, "videocount", entry["gd:feedLink"].xmlAttributes.countHint)>
  360.         <cfset querySetCell(results, "playlistID", entry["yt:playlistId"].xmlText)>
  361.     </cfloop>
  362.     <cfreturn results>
  363. </cffunction>
  364.  
  365. <cffunction name="getVideo" access="public" returnType="struct" output="false"
  366.             hint="Get one video.">
  367.     <cfargument name="myid" type="string" requied="true" hint="You can supply JUST the id, or the full URL">
  368.     <cfset var result = "">
  369.     <cfset var packet = "">
  370.     <cfset var entry = "">
  371.    
  372.     <!--- see if we provided a full url --->       
  373.     <cfif not find("/", arguments.myid)>
  374.         <cfset arguments.myid = "http://gdata.youtube.com/feeds/api/videos/#arguments.myid#">
  375.     </cfif>
  376.        
  377.     <cfhttp url="#arguments.myid#" result="result">
  378.     <cfset result = result.filecontent>
  379.     <cfif result is "Invalid id">
  380.         <cfthrow message="YouTubeCFC: Invalid id">
  381.     </cfif>
  382.     <cfset packet = xmlParse(result)>
  383.     <cfset entry = packet.entry>
  384.     <cfreturn parseEntry(entry)>
  385.    
  386. </cffunction>
  387.  
  388. <cffunction name="getVideos" access="private" returnType="any" output="false"
  389.             hint="Wrapper for video listing functions.">
  390.     <cfargument name="myurl" type="string" required="true">
  391.     <cfargument name="metaresult" type="boolean" required="false" default="false" hint="Used for getting complex data back from the results. Right now only used by search.">
  392.     <cfargument name="secure" type="boolean" required="false" default="false" hint="Only used for secure downloads. Calls will fail if not properly authenticated.">
  393.    
  394.     <cfset var result = "">
  395.     <cfset var packet = "">
  396.     <cfset var results = queryNew(
  397.     "videostatus,total,id,published,updated,categories,keywords,title,content,author,authorurl,link,description,duration,thumbnail_url,thumbnail_width,thumbnail_height,viewcount,favoritecount,averagerating,numratings,commentsurl,numcomments",
  398.     "varchar,integer,varchar,date,date,varchar,varchar,varchar,varchar,varchar,varchar,varchar,varchar,integer,varchar,integer,integer,integer,integer,integer,integer,varchar,integer")>
  399.     <cfset var x = "">
  400.     <cfset var entry = "">
  401.     <cfset var totalentries = "">
  402.     <cfset var pentry = "">
  403.     <cfset var key = "">
  404.     <cfset var meta = structNew()>
  405.     <cfset var links = "">
  406.    
  407.     <cfif arguments.secure>
  408.         <cfhttp url="#arguments.myurl#" method="get" result="result">
  409.             <cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#variables.authtoken#">
  410.             <cfhttpparam type="header" name="X-GData-Client" value="youtubecfc">
  411.             <cfhttpparam type="header" name="X-GData-Key" value="key=#variables.devkey#">
  412.         </cfhttp>
  413.     <cfelse>
  414.         <cfhttp url="#arguments.myurl#" result="result">   
  415.     </cfif>
  416.    
  417.     <cfset result = result.filecontent>
  418.     <cfset packet = xmlParse(result)>
  419.     <cfset totalentries = packet.feed["openSearch:totalResults"].xmlText>
  420.  
  421.    
  422.     <cfif structKeyExists(packet.feed, "entry")>
  423.         <cfloop index="x" from="1" to="#arrayLen(packet.feed.entry)#">
  424.             <cfset entry = packet.feed.entry[x]>
  425.             <cfset pentry = parseEntry(entry)>
  426.             <cfset queryAddRow(results)>
  427.             <cfset querySetCell(results, "total", totalentries)>
  428.             <cfloop item="key" collection="#pentry#">
  429.                 <cfset querySetCell(results, key, pentry[key])>
  430.             </cfloop>
  431.         </cfloop>
  432.     </cfif>
  433.        
  434.     <cfif not arguments.metaresult>
  435.         <cfreturn results>
  436.     <cfelse>
  437.         <cfset meta.results = results>
  438.         <!--- We will now put other info in the struct. For now its just spelling suggestions. --->
  439.         <cfset links = xmlSearch(packet, "//:link[@rel='http://schemas.google.com/g/2006##spellcorrection']")>
  440.         <cfif arrayLen(links)>
  441.             <cfset meta.suggestion = links[1].xmlAttributes.title>
  442.         </cfif>
  443.         <cfreturn meta>
  444.     </cfif>
  445. </cffunction>
  446.  
  447. <cffunction name="getMobileVideos" access="public" returnType="query" output="false"
  448.             hint="Gets mobile videos.">
  449.     <cfargument name="start" type="numeric" required="false">
  450.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  451.     <cfset var baseurl = variables.standardurl & "watch_on_mobile?">
  452.     <cfif structKeyExists(arguments, "start")>
  453.         <cfset baseurl &= "&start-index=#arguments.start#">
  454.     </cfif>
  455.     <cfif structKeyExists(arguments, "max")>
  456.         <cfset baseurl &= "&max-results=#arguments.max#">
  457.     </cfif>
  458.     <cfreturn getVideos(baseurl)>
  459. </cffunction>
  460.  
  461. <cffunction name="getMostDiscussedVideos" access="public" returnType="query" output="false"
  462.             hint="Gets the most discussed videos.">
  463.     <cfargument name="time" type="string" default="" hint="Restrict to: today,this_week,this_month,all_time">  
  464.     <cfargument name="start" type="numeric" required="false">
  465.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  466.     <cfset var baseurl = variables.standardurl & "most_discussed?">
  467.     <cfif len(arguments.time)>
  468.         <cfset baseurl = baseurl & "&time=#arguments.time#">
  469.     </cfif>
  470.     <cfif structKeyExists(arguments, "start")>
  471.         <cfset baseurl &= "&start-index=#arguments.start#">
  472.     </cfif>
  473.     <cfif structKeyExists(arguments, "max")>
  474.         <cfset baseurl &= "&max-results=#arguments.max#">
  475.     </cfif>
  476.    
  477.     <cfreturn getVideos(baseurl)>
  478. </cffunction>
  479.  
  480. <cffunction name="getMostRecentVideos" access="public" returnType="query" output="false"
  481.             hint="Gets the most recent videos.">
  482.     <cfargument name="start" type="numeric" required="false">
  483.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  484.     <cfset var baseurl = variables.standardurl & "most_recent?">
  485.     <cfif structKeyExists(arguments, "start")>
  486.         <cfset baseurl &= "&start-index=#arguments.start#">
  487.     </cfif>
  488.     <cfif structKeyExists(arguments, "max")>
  489.         <cfset baseurl &= "&max-results=#arguments.max#">
  490.     </cfif>
  491.     <cfreturn getVideos(baseurl)>
  492. </cffunction>
  493.  
  494. <cffunction name="getMostRespondedVideos" access="public" returnType="query" output="false"
  495.             hint="Gets the videos with the most responses.">
  496.     <cfargument name="time" type="string" default="" hint="Restrict to: today,this_week,this_month,all_time">                              
  497.     <cfargument name="start" type="numeric" required="false">
  498.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  499.     <cfset var baseurl = variables.standardurl & "most_responded?">
  500.     <cfif len(arguments.time)>
  501.         <cfset baseurl = baseurl & "&time=#arguments.time#">
  502.     </cfif>
  503.     <cfif structKeyExists(arguments, "start")>
  504.         <cfset baseurl &= "&start-index=#arguments.start#">
  505.     </cfif>
  506.     <cfif structKeyExists(arguments, "max")>
  507.         <cfset baseurl &= "&max-results=#arguments.max#">
  508.     </cfif>
  509.     <cfreturn getVideos(baseurl)>
  510. </cffunction>
  511.  
  512. <cffunction name="getMostViewedVideos" access="public" returnType="query" output="false"
  513.             hint="Gets most viewed videos.">
  514.     <cfargument name="time" type="string" default="" hint="Restrict to: today,this_week,this_month,all_time">              
  515.     <cfargument name="start" type="numeric" required="false">
  516.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  517.     <cfset var baseurl = variables.standardurl & "most_viewed?">
  518.     <cfif len(arguments.time)>
  519.         <cfset baseurl = baseurl & "&time=#arguments.time#">
  520.     </cfif>
  521.     <cfif structKeyExists(arguments, "start")>
  522.         <cfset baseurl &= "&start-index=#arguments.start#">
  523.     </cfif>
  524.     <cfif structKeyExists(arguments, "max")>
  525.         <cfset baseurl &= "&max-results=#arguments.max#">
  526.     </cfif>
  527.     <cfreturn getVideos(baseurl)>
  528. </cffunction>
  529.  
  530. <cffunction name="getRecentlyFeaturedVideos" access="public" returnType="query" output="false"
  531.             hint="Gets the recently featured videos.">
  532.     <cfargument name="start" type="numeric" required="false">
  533.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  534.     <cfset var baseurl = variables.standardurl & "recently_featured?">
  535.     <cfif structKeyExists(arguments, "start")>
  536.         <cfset baseurl &= "&start-index=#arguments.start#">
  537.     </cfif>
  538.     <cfif structKeyExists(arguments, "max")>
  539.         <cfset baseurl &= "&max-results=#arguments.max#">
  540.     </cfif>
  541.     <cfreturn getVideos(baseurl)>
  542. </cffunction>
  543.  
  544. <cffunction name="getTopFavoritesVideos" access="public" returnType="query" output="false"
  545.             hint="Gets the most favorited videos.">
  546.     <cfargument name="time" type="string" default="" hint="Restrict to: today,this_week,this_month,all_time">
  547.     <cfargument name="start" type="numeric" required="false">
  548.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  549.     <cfset var baseurl = variables.standardurl & "top_favorites?">
  550.     <cfif len(arguments.time)>
  551.         <cfset baseurl = baseurl & "&time=#arguments.time#">
  552.     </cfif>
  553.     <cfif structKeyExists(arguments, "start")>
  554.         <cfset baseurl &= "&start-index=#arguments.start#">
  555.     </cfif>
  556.     <cfif structKeyExists(arguments, "max")>
  557.         <cfset baseurl &= "&max-results=#arguments.max#">
  558.     </cfif>
  559.  
  560.     <cfreturn getVideos(baseurl)>
  561. </cffunction>
  562.  
  563. <cffunction name="getTopRatedVideos" access="public" returnType="query" output="false"
  564.             hint="Gets the top rated videos.">
  565.     <cfargument name="time" type="string" default="" hint="Restrict to: today,this_week,this_month,all_time">
  566.     <cfargument name="start" type="numeric" required="false">
  567.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  568.  
  569.     <cfset var baseurl = variables.standardurl & "top_rated?">
  570.     <cfif len(arguments.time)>
  571.         <cfset baseurl = baseurl & "&time=#arguments.time#">
  572.     </cfif>
  573.     <cfif structKeyExists(arguments, "start")>
  574.         <cfset baseurl &= "&start-index=#arguments.start#">
  575.     </cfif>
  576.     <cfif structKeyExists(arguments, "max")>
  577.         <cfset baseurl &= "&max-results=#arguments.max#">
  578.     </cfif>
  579.     <cfreturn getVideos(baseurl)>
  580. </cffunction>
  581.  
  582. <cffunction name="getVideosByCategoriesKeywords" access="public" returnType="query" output="false"
  583.             hint="Gets videos for a category or keyword.">
  584.     <cfargument name="categories" type="string" required="false">
  585.     <cfargument name="keywords" type="string" required="false">
  586.     <cfset var baseurl = "http://gdata.youtube.com/feeds/api/videos/-">
  587.    
  588.     <cfif not structKeyExists(arguments, "categories") and not structKeyExists(arguments, "keywords")>
  589.         <cfthrow message="YouTubeCFC Error: Must supply either a category or keyword to getVideosByCategoriesKeywords">
  590.     </cfif>
  591.    
  592.  
  593.     <cfif structKeyExists(arguments, "categories")>
  594.         <cfset arguments.categories = listChangeDelims(arguments.categories, "%7C")>
  595.         <cfset baseurl &= "/" & arguments.categories>
  596.     </cfif>
  597.     <cfif structKeyExists(arguments, "keywords")>
  598.         <cfset arguments.keywords = listChangeDelims(arguments.keywords, "/")>
  599.         <cfset baseurl &= "/" & arguments.keywords>
  600.     </cfif>
  601.  
  602.     <cfreturn getVideos(baseurl)>
  603. </cffunction>
  604.  
  605. <cffunction name="getVideosBySearch" access="public" returnType="query" output="false"
  606.             hint="Gets videos by a search.">
  607.     <cfargument name="search" type="string" required="true">
  608.     <cfargument name="orderby" type="string" required="false" hint="Valid values are: relevance,published,viewcount,rating, or relevance_lang_X">
  609.     <cfargument name="start" type="numeric" required="false">
  610.     <cfargument name="max" type="numeric" required="false" hint="Defaults to 25 in API, max is 50">
  611.     <cfargument name="author" type="string" required="false">
  612.     <cfargument name="lang" type="string" required="false" hint="Two-character language code to restrict results.">
  613.     <cfargument name="racy" type="boolean" required="false" hint="YouTube defaults to NOT-racy. How boring.">
  614.     <cfargument name="time" type="string" required="false" hint="all_time(default),today,this_week,this_month">
  615.     <cfargument name="autosearch" type="boolean" required="false" hint="If true, and results are 0 and suggestion != blank, will return a search for suggestion">
  616.  
  617.     <cfset var baseurl = "http://gdata.youtube.com/feeds/api/videos">
  618.     <cfset var result = "">
  619.     <cfset var newargs = "">
  620.    
  621.     <cfset baseurl &= "?v=2&q=#urlEncodedFormat(arguments.search)#">
  622.    
  623.     <cfif structKeyExists(arguments, "orderby")>
  624.         <cfset baseurl &= "&orderby=#arguments.orderby#">
  625.     </cfif>
  626.     <cfif structKeyExists(arguments, "start")>
  627.         <cfset baseurl &= "&start-index=#arguments.start#">
  628.     </cfif>
  629.     <cfif structKeyExists(arguments, "max")>
  630.         <cfset baseurl &= "&max-results=#arguments.max#">
  631.     </cfif>
  632.     <cfif structKeyExists(arguments, "author")>
  633.         <cfset baseurl &= "&author=#arguments.author#">
  634.     </cfif>
  635.     <cfif structKeyExists(arguments, "lang")>
  636.         <cfset baseurl &= "&lr=#arguments.lang#">
  637.     </cfif>
  638.     <cfif structKeyExists(arguments, "racy")>
  639.         <cfif arguments.racy>
  640.             <cfset baseurl &= "&racy=include">
  641.         <cfelse>
  642.             <cfset baseurl &= "&race=exclude">
  643.         </cfif>
  644.     </cfif>
  645.     <cfif structKeyExists(arguments, "time")>
  646.         <cfset baseurl &= "&time=#arguments.time#">
  647.     </cfif>
  648.  
  649.     <cfset result = getVideos(baseurl,true)>
  650.  
  651.     <!--- add suggestions column --->
  652.     <cfset queryAddColumn(result.results,"suggestion", "varchar", arrayNew(1))>
  653.     <cfif result.results.recordCount>
  654.         <cfif structKeyExists(result, "suggestion")>
  655.             <cfloop query="result.results">
  656.                 <cfset querySetCell(result.results, "suggestion", result.suggestion, currentRow)>
  657.             </cfloop>
  658.         </cfif>
  659.         <cfreturn result.results>
  660.     <cfelseif structKeyExists(result, "suggestion")>
  661.         <cfset newArgs = duplicate(arguments)>
  662.         <cfset newArgs.autosearch = false>
  663.         <cfset newArgs.search = result.suggestion>
  664.         <cfreturn getVideosBySearch(argumentCollection=newArgs)>
  665.     <cfelse>
  666.         <cfreturn result.results>
  667.     </cfif>
  668.    
  669. </cffunction>
  670.  
  671. <cffunction name="getVideosByUser" access="public" returnType="query" output="false"
  672.             hint="Gets videos for a user.">
  673.     <cfargument name="username" type="string" required="true">
  674.     <cfset var baseurl = "http://gdata.youtube.com/feeds/api/users/#arguments.username#/uploads">
  675.     <cfreturn getVideos(baseurl)>
  676. </cffunction>
  677.  
  678. <cffunction name="handleDate" access="public" returnType="date" output="false" hint="Utility function for dates.">
  679.     <cfargument name="datestr" type="string" required="true">
  680.     <cfset var date = listFirst(arguments.datestr,"T")>
  681.     <cfset var time = listLast(arguments.datestr,"T")>
  682.  
  683.     <!--- remove the Z from time - probably a bit dangerous --->
  684.     <cfset time = replace(time, "Z", "")>
  685.    
  686.     <cfset date = dateFormat(date,"short")>
  687.     <cfset time = timeFormat(listFirst(time,"-"),"short")> 
  688.     <cfreturn date & " " & time>   
  689. </cffunction>
  690.    
  691. <cffunction name="login" access="public" returnType="void" output="false"
  692.             hint="I authenticate a user and set the authtoken/username.">
  693.     <cfargument name="email" type="string" required="true" hint="Username, normally an email address.">
  694.     <cfargument name="password" type="string" required="true">
  695.     <cfset var theurl = "https://www.google.com/youtube/accounts/ClientLogin">
  696.     <cfset var result = "">
  697.     <cfset var lines = "">
  698.    
  699.     <cfhttp url="#theurl#" method="post" result="result">
  700.         <cfhttpparam type="formfield" name="Email" value="#arguments.email#">
  701.         <cfhttpparam type="formfield" name="Passwd" value="#arguments.password#">
  702.         <cfhttpparam type="formfield" name="service" value="youtube">  
  703.         <cfhttpparam type="formfield" name="source" value="youtubecfc">
  704.     </cfhttp>
  705.  
  706.     <cfset result = result.filecontent>
  707.  
  708.     <cfif not listFirst(result,"=") is "auth">
  709.         <cfthrow message="YouTubeCFC Login Error: #result#">
  710.     </cfif>
  711.  
  712.     <cfset lines = listToArray(result, chr(10))>
  713.     <cfset variables.authtoken = listRest(lines[1],"=")>
  714.     <cfset variables.username = listRest(lines[2],"=")>
  715.  
  716. </cffunction>
  717.  
  718. <cffunction name="parseEntry" access="private" returnType="struct" output="false" hint="I'm a utility function to parse Entry XML">
  719.     <cfargument name="entry" type="any" required="true">
  720.     <cfset var s = structNew()>
  721.     <cfset var y = "">
  722.     <cfset var keywordlist = "">
  723.     <cfset var categorylist = "">
  724.    
  725.     <cfset s.id = arguments.entry.id.xmlText>
  726.     <cfset s.published = "">
  727.     <cfif structKeyExists(arguments.entry, "published")>
  728.         <cfset s.published = handleDate(arguments.entry.published.xmlText)>
  729.     </cfif>
  730.     <cfset s.updated = handleDate(arguments.entry.updated.xmlText)>
  731.  
  732.     <cfloop index="y" from="1" to="#arrayLen(arguments.entry.category)#">
  733.         <cfif arguments.entry.category[y].xmlAttributes.scheme is "http://gdata.youtube.com/schemas/2007/keywords.cat">
  734.             <cfset keywordList = listAppend(keywordList, arguments.entry.category[y].xmlAttributes.term)>
  735.         <cfelseif entry.category[y].xmlAttributes.scheme is "http://gdata.youtube.com/schemas/2007/categories.cat">
  736.             <cfset categoryList = listAppend(categoryList, arguments.entry.category[y].xmlAttributes.term)>
  737.         </cfif>
  738.     </cfloop>
  739.  
  740.     <cfset s.keywords = keywordList>
  741.     <cfset s.categories = categoryList>
  742.     <cfset s.title = arguments.entry.title.xmlText>
  743.     <cfif structKeyExists(arguments.entry, "content")>
  744.         <cfset s.content = arguments.entry.content.xmlText>
  745.     <cfelse>
  746.         <cfset s.content = "">
  747.     </cfif>
  748.     <cfset s.author = arguments.entry.author.name.xmlText>
  749.     <cfset s.authorurl = entry.author.uri.xmlText>
  750.    
  751.     <cfset s.link = "">
  752.     <cfloop index="y" from="1" to="#arrayLen(arguments.entry.link)#">
  753.         <cfif arguments.entry.link[y].xmlAttributes.rel is "alternate" and arguments.entry.link[y].xmlAttributes.type is "text/html">
  754.             <cfset s.link = arguments.entry.link[y].xmlattributes.href>
  755.         </cfif>
  756.     </cfloop>
  757.    
  758.     <cfset s.description = "">
  759.     <cfset s.duration = "">
  760.     <cfset s.thumbnail_url = "">
  761.     <cfset s.thumbnail_width = "">
  762.     <cfset s.thumbnail_height = "">
  763.     <cfif structKeyExists(arguments.entry, "media:group")>
  764.         <cfif structKeyExists(arguments.entry["media:group"], "media:description")>
  765.             <cfset s.description = arguments.entry["media:group"]["media:description"].xmltext>
  766.         <cfelse>
  767.             <cfset s.description = "">
  768.         </cfif>
  769.         <cfif structKeyExists(arguments.entry, "yt:duration")>
  770.             <cfset s.duration = arguments.entry["media:group"]["yt:duration"].xmlattributes.seconds>
  771.         <cfelse>
  772.             <cfset s.duration = "">
  773.         </cfif>
  774.         <cfif structKeyExists(arguments.entry["media:group"], "media:thumbnail")>      
  775.             <!--- Thumbnail is complex, has multiple records, but for getvideos, we will show just the first one. --->
  776.             <cfset s.thumbnail_url = arguments.entry["media:group"]["media:thumbnail"].xmlAttributes.url>
  777.             <cfset s.thumbnail_width = arguments.entry["media:group"]["media:thumbnail"].xmlAttributes.width>
  778.             <cfset s.thumbnail_height =  arguments.entry["media:group"]["media:thumbnail"].xmlAttributes.height>
  779.         <cfelse>
  780.             <cfset s.thumbnail_url = "">
  781.             <cfset s.thumbnail_width = "">
  782.             <cfset s.thumbnail_height = "">
  783.         </cfif>
  784.     </cfif>
  785.  
  786.     <cfset s.viewcount = "">
  787.     <cfset s.favoritecount = "">
  788.    
  789.     <cfif structKeyExists(arguments.entry, "yt:statistics")>
  790.         <cfif structKeyExists(arguments.entry["yt:statistics"].xmlAttributes, "viewCount")>
  791.             <cfset s.viewcount = arguments.entry["yt:statistics"].xmlAttributes.viewcount>
  792.         </cfif>
  793.         <cfif structKeyExists(arguments.entry["yt:statistics"].xmlAttributes, "favoriteCount")>
  794.             <cfset s.favoritecount = arguments.entry["yt:statistics"].xmlAttributes.favoritecount>
  795.         </cfif>
  796.     </cfif>
  797.  
  798.     <cfset s.averagerating = "">
  799.     <cfset s.numratings = "">
  800.     <cfif structKeyExists(arguments.entry, "gd:rating")>
  801.         <cfset s.averagerating = arguments.entry["gd:rating"].xmlAttributes.average>
  802.         <cfset s.numratings = arguments.entry["gd:rating"].xmlAttributes.numraters>
  803.     </cfif>
  804.  
  805.     <cfif structKeyExists(arguments.entry, "gd:comments")>
  806.         <cfset s.commentsurl = arguments.entry["gd:comments"]["gd:feedlink"].xmlAttributes.href>
  807.         <cfset s.numcomments = arguments.entry["gd:comments"]["gd:feedlink"].xmlAttributes.countHint>
  808.     </cfif>
  809.  
  810.     <cfset s.videostatus = "public">
  811.     <cfif structKeyExists(arguments.entry, "app:control") and structKeyExists(arguments.entry["app:control"], "yt:state")>
  812.         <cfif structKeyExists( arguments.entry["app:control"]["yt:state"].xmlAttributes, "reasonCode")>
  813.             <cfset s.videostatus = arguments.entry["app:control"]["yt:state"].xmlAttributes.reasonCode>
  814.         <cfelseif structKeyExists( arguments.entry["app:control"]["yt:state"].xmlAttributes, "name")>
  815.             <cfset s.videostatus = arguments.entry["app:control"]["yt:state"].xmlAttributes.name>
  816.         </cfif>
  817.     </cfif>
  818.    
  819.     <cfreturn s>
  820.  
  821. </cffunction>
  822.  
  823. <cffunction name="setDeveloperKey" access="public" returnType="void" output="false"
  824.             hint="Sets the developer key for the CFC.">
  825.     <cfargument name="devkey" type="string" required="true">
  826.     <cfset variables.devkey = arguments.devkey>
  827. </cffunction>
  828.  
  829. <cffunction name="update" access="public" returnType="any" output="false" hint="I update a video.">
  830.     <cfargument name="title" type="string" required="true">
  831.     <cfargument name="description" type="string" required="true">
  832.     <cfargument name="categories" type="string" required="true">
  833.     <cfargument name="keywords" type="string" required="true">
  834.     <cfargument name="videoId" type="string" required="true">
  835.    
  836.     <cfset var theurl = "http://uploads.gdata.youtube.com/feeds/api/users/#variables.username#/uploads/">
  837.     <cfset var result = "">
  838.     <cfset var meta = "">
  839.     <cfset var resxml = "">
  840.     <cfset var tmpFile = expandPath("./#replace(createUUID(),'-','_','all')#")>
  841.  
  842.     <cfset theurl &=  arguments.videoId />
  843.     <!--- todo, validate the categories --->
  844.     <cfsavecontent variable="meta">
  845.     <cfoutput>
  846. <?xml version="1.0"?>
  847. <entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">
  848. <media:group>
  849.     <media:title type="plain">#arguments.title#</media:title>
  850.     <media:description type="plain">#arguments.description#</media:description>
  851.     <media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">#arguments.categories#</media:category>
  852.     <media:keywords>#xmlFormat(fixKeywords(arguments.keywords))#</media:keywords>
  853. </media:group>
  854. </entry>
  855.     </cfoutput>
  856.     </cfsavecontent>
  857.  
  858.     <cfset meta = trim(meta)>
  859.     <cfhttp url="#theurl#" method="put" result="result">
  860.         <cfhttpparam type="header" name="Host" value="gdata.youtube.com">
  861.         <cfhttpparam type="header" name="Content-Type" value="application/atom+xml">
  862.         <cfhttpparam type="header" name="Content-Length" value="#len(meta)#">
  863.         <cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#variables.authtoken#">
  864.         <cfhttpparam type="header" name="X-GData-Client" value="youtubecfc">
  865.         <cfhttpparam type="header" name="X-GData-Key" value="key=#variables.devkey#">
  866.         <cfhttpparam type="header" name="rel" value="edit">
  867.         <cffile action="write" file="#tmpfile#" output="#meta#">
  868.         <cfhttpparam type="file" name="API_XML_Request" file="#tmpfile#" mimetype="application/atom+xml">
  869.     </cfhttp>
  870.    
  871.     <cffile action="delete" file="#tmpfile#">
  872.    
  873.     <cfif result.responseheader.explanation is "OK">
  874.         <cfset resxml = xmlParse(result.fileContent)>
  875.         <cfreturn resxml.entry.id.xmlText>
  876.     <cfelse>
  877.     <cfoutput>#theurl#<p>#htmlcodeformat(meta)#</cfoutput>
  878.     <cfdump var="#result#" abort>
  879.         <cfif isXml(result.filecontent)>
  880.             <cfset resxml = xmlParse(result.fileContent)>
  881.             <cfthrow message="YouTubeCFC Upload Error: Domain=#resxml.errors.error.domain.xmlText#, Code=#resxml.errors.error.code.xmlText#">
  882.         <cfelse>
  883.             <cfthrow message="YouTubeCFC Upload Error: Status: #result.responseheader.status_code# / Explanation: #result.responseheader.explanation#">
  884.         </cfif>
  885.     </cfif>
  886.  
  887. </cffunction>  
  888.  
  889. <cffunction name="upload" access="public" returnType="any" output="false" hint="I upload a video.">
  890.     <cfargument name="video" type="string" required="true">
  891.     <cfargument name="title" type="string" required="true">
  892.     <cfargument name="description" type="string" required="true">
  893.     <cfargument name="categories" type="string" required="true">
  894.     <cfargument name="keywords" type="string" required="true">
  895.    
  896.     <cfset var theurl = "http://uploads.gdata.youtube.com/feeds/api/users/#variables.username#/uploads/">
  897.     <cfset var result = "">
  898.     <cfset var meta = "">
  899.     <cfset var tmpFile = expandPath("./#replace(createUUID(),'-','_','all')#")>
  900.     <cfset var resxml = "">
  901.    
  902.     <cfif not fileExists(arguments.video)>
  903.         <cfthrow message="YouTubeCFC Upload Error: The video (#arguments.video#) could not be found.">
  904.     </cfif>
  905.  
  906.     <!--- todo, validate the categories --->
  907.     <cfsavecontent variable="meta">
  908.     <cfoutput>
  909. <?xml version="1.0"?>
  910. <entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">
  911. <media:group>
  912.     <media:title type="plain">#xmlFormat(arguments.title)#</media:title>
  913.     <media:description type="plain">#xmlFormat(arguments.description)#</media:description>
  914.     <media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">#arguments.categories#</media:category>
  915.     <media:keywords>#xmlFormat(fixKeywords(arguments.keywords))#</media:keywords>
  916. </media:group>
  917. </entry>
  918.     </cfoutput>
  919.     </cfsavecontent>
  920.     <cfset meta = trim(meta)>
  921.  
  922.     <!--- store the xml --->
  923.     <cffile action="write" file="#tmpfile#" output="#meta#">
  924.  
  925.     <cfhttp url="#theurl#" method="post" result="result" multiparttype="related">
  926.         <cfhttpparam type="header" name="Authorization" value="GoogleLogin auth=#variables.authtoken#">
  927.         <cfhttpparam type="header" name="X-GData-Client" value="youtubecfc">
  928.         <cfhttpparam type="header" name="X-GData-Key" value="key=#variables.devkey#">
  929.         <cfhttpparam type="header" name="Slug" value="#listLast(arguments.video,"\/")#">
  930.         <cfhttpparam type="file" name="API_XML_Request" file="#tmpfile#" mimetype="application/atom+xml; charset=UTF-8 ">
  931.         <cfhttpparam type="file" name="file" file="#arguments.video#" mimetype="video/*">  
  932.     </cfhttp>
  933.     <cffile action="delete" file="#tmpfile#">
  934.  
  935.     <cfif result.responseheader.explanation is "created">
  936.         <cfset resxml = xmlParse(result.fileContent)>
  937.         <cfreturn resxml.entry.id.xmlText>
  938.     <cfelse>
  939.         <cfif isXml(result.filecontent)>
  940.             <cfset resxml = xmlParse(result.fileContent)>
  941.             <cfthrow message="YouTubeCFC Upload Error: Domain=#resxml.errors.error.domain.xmlText#, Code=#resxml.errors.error.code.xmlText#">
  942.         <cfelse>
  943.             <cfdump var="#result#" abort>
  944.             <cfthrow message="YouTubeCFC Upload Error: Status: #result.responseheader.status_code# / Explanation: #result.responseheader.explanation#">
  945.         </cfif>
  946.     </cfif>
  947.  
  948. </cffunction>  
  949.  
  950. </cfcomponent>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement