PageRenderTime 26ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/from_1.1-1.2/components/Updater.cfc

https://bitbucket.org/asfusion/mango-updates
ColdFusion CFScript | 401 lines | 313 code | 79 blank | 9 comment | 10 complexity | 15fd17cc18d0dfba1918380dfaf2d4ff MD5 | raw file
  1. <cfcomponent>
  2. <cffunction name="init" access="public" output="false" returntype="any">
  3. <cfargument name="applicationManager" required="true" type="any">
  4. <cfargument name="configFile" required="false" type="string" default="" hint="Path to config file"/>
  5. <cfargument name="baseDirectory" type="string" required="true" />
  6. <cfset variables.blogManager = arguments.applicationManager />
  7. <cfset variables.configFile = arguments.configFile />
  8. <cfset variables.baseDirectory = arguments.baseDirectory />
  9. <cfreturn this />
  10. </cffunction>
  11. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  12. <cffunction name="downloadSkin" access="public" output="false" returntype="struct">
  13. <cfargument name="skin" type="String" required="true" />
  14. <cfset var ftp = "" />
  15. <cfset var connection = "" />
  16. <cfset var skinInfo = "" />
  17. <cfset var exists = "">
  18. <cfset var skinsDir = variables.blogManager.getBlog().getSetting('skinsDirectory') />
  19. <cfset var result = structnew()/>
  20. <cfset result.message = createObject("component","Message") />
  21. <cfset result.message.setstatus("success") />
  22. <cfset result.message.setText("Skin downloaded and available to use") />
  23. <cftry>
  24. <!--- check if this skin is compatible --->
  25. <cfinvoke webservice="http://www.mangoblog.org/services/Update.cfc?wsdl" method="getSkinInfo" timeout="5" returnvariable="skinInfo"><cfinvokeargument name="skin" value="#arguments.skin#"></cfinvoke>
  26. <cfif versionCompare(skinInfo.requiresVersion, variables.blogManager.getVersion()) LT 1>
  27. <!--- try to get ftp data from web service --->
  28. <cfinvoke webservice="http://www.mangoblog.org/services/Update.cfc?wsdl" method="getSkinFTP" timeout="5" returnvariable="ftp">
  29. <cftry>
  30. <!--- open connection and check if it exists --->
  31. <cfftp connection="connection" server="#ftp.server#" username="#ftp.username#"
  32. password="#ftp.password#" stoponerror="Yes" action="open" passive="true">
  33. <cfftp action="existsdir" directory="#ftp.directory##arguments.skin#" connection="connection" result="exists">
  34. <cfif exists.returnValue>
  35. <!--- download it and save skin in skin directory --->
  36. <cfset ftpcopy(ftp.server, ftp.username, ftp.password, "#ftp.directory##arguments.skin#", skinsDir) />
  37. <cfelse>
  38. <cfset result.message.setstatus("error") />
  39. <cfset result.message.setText("Selected skin cannot be found.") />
  40. </cfif>
  41. <cfcatch type="any">
  42. <!--- try simple download->unzip route --->
  43. <cftry>
  44. <cfset httpDownload(skinInfo.downloadUrl, skinsDir & arguments.skin & "/")>
  45. <cfcatch type="any"><!--- didn't work out either --->
  46. <cfset result.message.setstatus("ftp_error") />
  47. <cfset result.message.setText(skinInfo.downloadUrl) />
  48. </cfcatch>
  49. </cftry>
  50. </cfcatch>
  51. </cftry>
  52. <cfelse>
  53. <cfset result.message.setstatus("error") />
  54. <cfset result.message.setText("Selected skin requires a newer version of Mango Blog than the one it is installed.") />
  55. </cfif>
  56. <cfcatch type="any">
  57. <cfset result.message.setstatus("error") />
  58. <cfset result.message.setText(cfcatch.Message) />
  59. </cfcatch>
  60. </cftry>
  61. <cfreturn result />
  62. </cffunction>
  63. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  64. <cffunction name="checkForUpdates" access="public" output="false" returntype="string">
  65. <cfset var latestVersion = 0 />
  66. <cfset var message = "">
  67. <cftry>
  68. <cfinvoke webservice="http://www.mangoblog.org/services/Update.cfc?wsdl"
  69. method="getCurrentVersionNumber" timeout="5" returnvariable="latestVersion">
  70. <cfif versionCompare(latestVersion, variables.blogManager.getVersion()) EQ 1>
  71. <cftry>
  72. <cfinvoke webservice="http://www.mangoblog.org/services/Update.cfc?wsdl" method="getUpdateInstructions" timeout="10" returnvariable="message">
  73. <cfinvokeargument name="version" value="#variables.blogManager.getVersion()#">
  74. </cfinvoke>
  75. <cfcatch type="any">
  76. <!--- since I changed the methods on the webservice, it is possible
  77. that this server has the definitions cached. So, for the moment, try another url --->
  78. <cfinvoke webservice="http://www.mangoblog.org/services/Update2.cfc?wsdl" method="getUpdateInstructions" timeout="10" returnvariable="message">
  79. <cfinvokeargument name="version" value="#variables.blogManager.getVersion()#">
  80. </cfinvoke>
  81. </cfcatch>
  82. </cftry>
  83. </cfif>
  84. <cfcatch type="any"></cfcatch>
  85. </cftry>
  86. <cfreturn message />
  87. </cffunction>
  88. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  89. <cffunction name="executeUpdate" access="public" output="true">
  90. <cfset var updatePlan = arraynew(1) />
  91. <cfset var i = 0 />
  92. <cfset var stepResult = structnew() />
  93. <cfset var serverVersion = structnew() />
  94. <cfset stepResult.message = createObject("component","Message") />
  95. <cfset stepResult.message.setstatus("success") />
  96. <cfset stepResult.message.setText('Update done') />
  97. <cftry>
  98. <cfif structkeyexists(server, "coldfusion")>
  99. <cfset serverVersion.productname = server.coldfusion.productname />
  100. <cfset serverVersion.productversion = server.coldfusion.productversion />
  101. </cfif>
  102. <cftry>
  103. <!--- call Mango services to get the upgrade plan --->
  104. <cfinvoke webservice="http://www.mangoblog.org/services/Update.cfc?wsdl" method="getUpdatePlan"
  105. timeout="10" returnvariable="updatePlan">
  106. <cfinvokeargument name="version" value="#variables.blogManager.getVersion()#">
  107. <cfinvokeargument name="serverInfo" value="#serverVersion#">
  108. </cfinvoke>
  109. <cfcatch type="any">
  110. <!--- since I changed the methods on the webservice, it is possible
  111. that this server has the definitions cached. So, for the moment, try another url --->
  112. <cfinvoke webservice="http://www.mangoblog.org/services/Update2.cfc?wsdl" method="getUpdatePlan" timeout="10" returnvariable="updatePlan">
  113. <cfinvokeargument name="version" value="#variables.blogManager.getVersion()#">
  114. <cfinvokeargument name="serverInfo" value="#serverVersion#">
  115. </cfinvoke>
  116. </cfcatch>
  117. </cftry>
  118. <cfloop from="1" to="#arraylen(updatePlan)#" index="i">
  119. <p> <strong>Updating to version #updatePlan[i].updatesToVersion#</strong><br /><br /></p>
  120. <cfset stepResult = downloadUpdate(updatePlan[i].updateFileUrl,
  121. updatePlan[i].runnerFile,
  122. updatePlan[i].fileIsZip) />
  123. <cfif stepResult.message.getStatus() NEQ "success">
  124. <cfreturn stepResult />
  125. </cfif>
  126. </cfloop>
  127. <cfset variables.blogManager.removeCurrentUser() />
  128. <cfset variables.blogManager.reloadConfig() />
  129. <cfcatch type="any">
  130. <cfset stepResult.message.setstatus("error") />
  131. <cfset stepResult.message.setText("Upgrade could not be performed: " & cfcatch.Message) />
  132. </cfcatch>
  133. </cftry>
  134. <cfreturn stepResult />
  135. </cffunction>
  136. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  137. <!--- very important function. It will download and replace files and do everything needed to
  138. update mango's version --->
  139. <cffunction name="downloadUpdate" access="public" output="true" returntype="struct">
  140. <cfargument name="remoteUpdateFile" type="string" required="true" />
  141. <cfargument name="runnerFile" type="string" required="true" />
  142. <cfargument name="isZipped" type="boolean" required="false" default="false" />
  143. <cfset var tempDir = GetDirectoryFromPath(GetCurrentTemplatePath()) & "updater_temp/" />
  144. <cfset var result = structnew()/>
  145. <cfset var local = structnew() />
  146. <cfset local.baseDirectory = variables.baseDirectory />
  147. <cfset local.configFile = variables.configFile />
  148. <cfset local.componentsPath = GetDirectoryFromPath(GetCurrentTemplatePath()) />
  149. <cfset result.message = createObject("component","Message") />
  150. <cfset result.message.setstatus("success") />
  151. <cfset result.message.setText('<br /><strong>Updated done!</strong><br />
  152. You will now be logged out. <a href="index.cfm">Click here to continue</a>.') />
  153. <cftry>
  154. <p>Downloading files...
  155. <!--- the simplest way is to download one file and then simply include it and run it... --->
  156. <cfset httpDownload(arguments.remoteUpdateFile, tempDir, arguments.isZipped) />
  157. done <br />
  158. Starting the update</p>
  159. <cfinclude template="updater_temp/#runnerFile#" />
  160. <!--- remove update files --->
  161. <p>Deleting temporary files...
  162. <cfdirectory action="delete" directory="#tempDir#" recurse="true">
  163. done
  164. </p>
  165. <cfcatch type="any">
  166. <cfset result.message.setstatus("error") />
  167. <cfset result.message.setText("Upgrade could not be performed: " & cfcatch.Message) />
  168. </cfcatch>
  169. </cftry>
  170. <cfreturn result />
  171. </cffunction>
  172. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  173. <cffunction name="ftpcopy" access="private" output="false">
  174. <cfargument name="server" required="true" type="any">
  175. <cfargument name="username" required="true" type="string">
  176. <cfargument name="password" required="true" type="string">
  177. <cfargument name="dir" required="true" type="any">
  178. <cfargument name="localdir" required="true" type="string">
  179. <cfset var dirs = "" />
  180. <!--- create local dir if needed --->
  181. <cfif NOT directoryExists(arguments.localdir & arguments.dir)>
  182. <cfdirectory action="create" directory="#arguments.localdir##arguments.dir#">
  183. </cfif>
  184. <cfftp server="#arguments.server#" username="#arguments.username#" passive="true"
  185. password="#arguments.password#" action="listdir" name="dirs" directory="#arguments.dir#">
  186. <cfoutput query="dirs">
  187. <cfif isDirectory>
  188. <!--- copy folder --->
  189. <cfset ftpcopy(arguments.server, arguments.username, arguments.password,
  190. Path, arguments.localdir)>
  191. <cfelse>
  192. <!--- copy file --->
  193. <cfftp server="#arguments.server#" username="#arguments.username#"
  194. password="#arguments.password#" passive="true"
  195. action="getFile" localfile="#arguments.localdir##path#"
  196. remotefile="#path#"
  197. failifexists="No">
  198. </cfif>
  199. </cfoutput>
  200. </cffunction>
  201. <!--- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: --->
  202. <cffunction name="httpDownload" access="private" output="false">
  203. <cfargument name="zipAddress" required="true" type="any">
  204. <cfargument name="localdir" required="true" type="string">
  205. <cfargument name="isZip" required="false" type="boolean" default="true">
  206. <cfset var tempdir = GetDirectoryFromPath(GetCurrentTemplatePath()) & "temp/">
  207. <cfset var zip = "" />
  208. <cfset var filename = listlast(zipaddress,"/") />
  209. <cfif NOT directoryexists(tempdir)>
  210. <cfdirectory action="create" directory="#tempdir#">
  211. </cfif>
  212. <cfhttp url="#arguments.zipAddress#" method="get" path="#tempdir#">
  213. <cfif NOT directoryexists(localdir)>
  214. <cfdirectory action="create" directory="#localdir#">
  215. </cfif>
  216. <cfif arguments.isZip>
  217. <cfset unzipFile(tempdir & filename, localdir) />
  218. <cfelse><!--- not a zip file, simply copy it to the destination directory --->
  219. <cffile action="copy" source="#tempdir##filename#" destination="#localdir#">
  220. </cfif>
  221. <!--- delete the zip file --->
  222. <cftry>
  223. <!--- if we did everything but couldn't delete the zip, no big deal --->
  224. <cffile action="delete" file="#tempdir##filename#" />
  225. <cfdirectory action="delete" directory="#tempdir#" recurse="true">
  226. <cfcatch type="any"></cfcatch>
  227. </cftry>
  228. <cfreturn />
  229. </cffunction>
  230. <cfscript>
  231. /**
  232. * Unzips a file to the specified directory.
  233. *
  234. * @param zipFilePath Path to the zip file (Required)
  235. * @param outputPath Path where the unzipped file(s) should go (Required)
  236. * @return void
  237. * @author Samuel Neff (sam@serndesign.com)
  238. * @version 1, September 1, 2003
  239. */
  240. function unzipFile(zipFilePath, outputPath) {
  241. var zipFile = ""; // ZipFile
  242. var entries = ""; // Enumeration of ZipEntry
  243. var entry = ""; // ZipEntry
  244. var fil = ""; //File
  245. var inStream = "";
  246. var filOutStream = "";
  247. var bufOutStream = "";
  248. var nm = "";
  249. var pth = "";
  250. var lenPth = "";
  251. var buffer = "";
  252. var l = 0;
  253. zipFile = createObject("java", "java.util.zip.ZipFile");
  254. zipFile.init(zipFilePath);
  255. entries = zipFile.entries();
  256. while(entries.hasMoreElements()) {
  257. entry = entries.nextElement();
  258. if(NOT entry.isDirectory()) {
  259. nm = entry.getName();
  260. lenPth = len(nm) - len(getFileFromPath(nm));
  261. if (lenPth) {
  262. pth = outputPath & left(nm, lenPth);
  263. } else {
  264. pth = outputPath;
  265. }
  266. if (NOT directoryExists(pth)) {
  267. fil = createObject("java", "java.io.File");
  268. fil.init(pth);
  269. fil.mkdirs();
  270. }
  271. filOutStream = createObject(
  272. "java",
  273. "java.io.FileOutputStream");
  274. filOutStream.init(outputPath & nm);
  275. bufOutStream = createObject(
  276. "java",
  277. "java.io.BufferedOutputStream");
  278. bufOutStream.init(filOutStream);
  279. inStream = zipFile.getInputStream(entry);
  280. buffer = repeatString(" ",1024).getBytes();
  281. l = inStream.read(buffer);
  282. while(l GTE 0) {
  283. bufOutStream.write(buffer, 0, l);
  284. l = inStream.read(buffer);
  285. }
  286. inStream.close();
  287. bufOutStream.close();
  288. }
  289. }
  290. zipFile.close();
  291. }
  292. </cfscript>
  293. <cffunction name="versionCompare" returntype="numeric" access="public">
  294. <cfargument name="version1">
  295. <cfargument name="version2">
  296. <cfset var len1 = listlen(arguments.version1,".") />
  297. <cfset var len2 = listlen(arguments.version2,".") />
  298. <cfset var i = 0/>
  299. <cfset var piece1 = ""/>
  300. <cfset var piece2 = ""/>
  301. <cfif len1 GT len2>
  302. <cfset arguments.version2 = arguments.version2 & repeatstring(".0",len1-len2) />
  303. </cfif>
  304. <cfif len1 LT len2>
  305. <cfset arguments.version1 = arguments.version1 & repeatstring(".0",len2-len1) />
  306. </cfif>
  307. <cfloop from="1" to="#listlen(arguments.version1,".")#" index="i">
  308. <cfset piece1 = listgetat(arguments.version1,i,".")/>
  309. <cfset piece2 = listgetat(arguments.version2,i,".")/>
  310. <cfif piece1 NEQ piece2>
  311. <!--- we need to compare --->
  312. <cfif piece1 GT piece2>
  313. <cfreturn 1/>
  314. <cfelse>
  315. <cfreturn -1/>
  316. </cfif>
  317. </cfif>
  318. </cfloop>
  319. <!--- they were equal --->
  320. <cfreturn 0/>
  321. </cffunction>
  322. </cfcomponent>