Advertisement
Dermotb

Backup 1.00

Mar 11th, 2013
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.20 KB | None | 0 0
  1. --# Notes
  2. --[[
  3. This utility backs up and restores your projects for you, by storing them as images in your Dropbox folder.
  4. Its features are as follows:
  5. 1. backs up up behind the scenes every time you change the version number
  6. 2. tells you how long it is since the last backup
  7. 3. restores your backup into a new project, tabs and all
  8.  
  9. INSTALLING IT
  10. Copy this project to your Codea, named as Backup
  11.  
  12. BACKING UP
  13.  
  14. Include a line like this in your function setup()
  15. b=Backup("MyProject Ver 1.00")
  16.  
  17. Also create a dependency to the Backup project
  18. (click the + at upper right of screen, find Backup on the project list, and press it)
  19.  
  20. The utility will only back up when the string in brackets changes. It will create a new image with that name
  21. in your Dropbox folder (you may need to sync to see it). The reason for not backing up every time you run, is that when you are developing, you will try a lot of stuff, and you may get into a mess. You will then want to go back to your last stable version. So the idea is that whenever you are at a checkpoint, make a new version name.
  22.  
  23. RESTORING
  24.  
  25. Create a new project to hold your restored project, and put this in function setup()
  26. img=readImage("Dropbox:AAA")
  27. r=Restore(img)
  28.  
  29. Now change the image name to the Dropbox file you want to restore
  30.  
  31. BEFORE YOU RUN, create a dependency to the Backup project
  32. (click the + at upper right of screen, find Backup on the project list, and press it)
  33.  
  34. Now run, and when it's done, go back to the code and it should all be there.
  35.  
  36. Ignatz version 1.00 March 2013
  37. --]]
  38. --# Main
  39. function setup()
  40.  
  41. end
  42.  
  43.  
  44. --# Backup
  45. Backup = class()
  46.  
  47. function Backup:init(title)
  48. t=readProjectData(title)
  49. if t~=nil then
  50. print("Last backup was",string.format("%.0f",os.difftime(os.time(),t)/60),"minutes ago")
  51. --print(os.time(),t)
  52. else
  53. self:Store(title)
  54. saveProjectData(title,os.time())
  55. end
  56. end
  57.  
  58. function Backup:Store(title)
  59. local txt=""
  60. local origTxt=""
  61. local tabs=listProjectTabs()
  62. for i,t in pairs(tabs) do
  63. origTxt=origTxt..readProjectTab(t)
  64. end
  65. txt=origTxt..string.rep("#",10)
  66. local n=3-string.len(txt)%3
  67. if n>0 then txt=txt..string.sub("0000",1,n) end
  68. n=string.len(txt)
  69. local s=math.floor((n/3)^.5)+1
  70. img=image(s,s)
  71. local row,col=0,1
  72. local e={}
  73. local m=0
  74. for i=0,n-1,3 do
  75. for j=1,3 do
  76. e[j]=string.byte(string.sub(txt,i+j,i+j))
  77. end
  78. row = row + 1
  79. if row>s then row=1 col = col + 1 end
  80. img:set(col,row,e[1],e[2],e[3],255)
  81. end
  82. docName="Dropbox:"..title
  83. saveImage(docName,nil)
  84. saveImage(docName,img)
  85. print(title.." - backup made")
  86. local r=Restore(img,true)
  87. if origTxt==r.txt then
  88. print("Backup verified")
  89. else
  90. print(string.len(origTxt),string.len(txt1))
  91. print(string.sub(origTxt,1,500)==string.sub(txt1,1,500))
  92. end
  93. end
  94.  
  95.  
  96.  
  97. --# Restore
  98. Restore = class()
  99.  
  100. function Restore:init(img,test)
  101. --print("Recovering text")
  102. self.txt=self:ReadImage(img)
  103. --print("Text recovered")
  104. if self.txt=="ERROR" then
  105. if test~=true then print("ERROR: I couldn't read the file") end
  106. else
  107. if test~=true then s=Splitter(self.txt) end
  108. end
  109. end
  110.  
  111. function Restore:ReadImage(img)
  112. if type(img)=="string" then img=readImage(img) end
  113. rows,cols=img.height,img.width
  114. t={}
  115. local n=0
  116. local r,g,b,a
  117. for col=1,cols do
  118. for row=1,rows do
  119. r,g,b,a=img:get(col,row)
  120. table.insert(t,string.char(r))
  121. table.insert(t,string.char(g))
  122. table.insert(t,string.char(b))
  123. n = n + 3
  124. end
  125. end
  126. local txt= table.concat(t)
  127. n=string.find(txt,string.rep("#",10))
  128. if n~=nil then txt=string.sub(txt,1,n-1) else txt="ERROR" end
  129. return txt
  130. end
  131. --# Splitter
  132. Splitter=class()
  133.  
  134. --# Main
  135. --Main
  136. --[[
  137. CodeSplitter version 1.0 March 2013 by Ignatz
  138.  
  139. This utility splits the class code in a project into separate tabs
  140. To use it, create a new project and paste all the code into the Main tab
  141. Put the name of the project in below and run
  142. --]]
  143.  
  144. --function setup()
  145. -- SplitCode("Track") -- < name of your project goes in here
  146. --end
  147.  
  148. function Splitter:init(txt)
  149. self:SplitCode(txt)
  150. end
  151.  
  152. function Splitter:SplitCode(txt)
  153. --get total code
  154. --local txt=readProjectTab(nam..":Main")
  155. --initialise, see below
  156. local prevClassName,prevIndex="",1
  157. local str
  158. --it is quite difficult to find the start of a class, if you want to include
  159. --any preceding comments
  160. --this utility uses the fact that all classes end with a function, which in turn ends with "end"
  161. --so it splits the entire code into chunks, all of which end with a line feed followed by "end"
  162. local s="\nend" --the text we'll split on
  163. local f=split(txt,s) --split using function underneath
  164. for i=1,#f do --loop through chunks
  165. if i<#f then f[i] = f[i]..s end --the act of splitting deleted the "end" text, put it back
  166. c=f[i]:match("(%w+) ?= ?class") --this regex finds the class name
  167. if c==nil then
  168. local x= f[i]:find("function setup()",nil,true)
  169. if x~=nil then c="Main" end --this regex looks for the Main tab via setup
  170. end
  171. --if there is a classname, then the functions from here on belong to it - until we hit the
  172. -- next classname or the end
  173. --the functions preceding this chunk belong to the previous class, whose name we have cunningly
  174. --stored. For the first one, we have set it to Main
  175. if c~=nil then
  176. str="" --concatenate all the chunks since the previous class was written
  177. for j=prevIndex,i-1 do
  178. str=str..f[j]
  179. end
  180. str=str:match( "^%s*(.+)" ) --remove leading white space
  181. print("Saving",prevClassName)
  182. saveProjectTab(prevClassName,str) --write them to a tab
  183. prevClassName=trim(c)
  184. prevIndex=i
  185. end
  186. end
  187. --finish off the remaining text, which belongs to the last classname we have stored
  188. if prevClassName~=nil then
  189. str=""
  190. for j=prevIndex,#f do
  191. str=str..f[j]
  192. end
  193. str=str:match( "^%s*(.+)" ) --remove leading white spacew
  194. saveProjectTab(prevClassName,str)
  195. print("Saving",prevClassName)
  196. end
  197. print("All done!")
  198. end
  199.  
  200. function trim(s)
  201. return s:match("^%s*(.-)%s*$")
  202. end
  203.  
  204. -- Compatibility: Lua-5.0
  205. --http://lua-users.org/wiki/SplitJoin
  206. function split(str, delim, maxNb)
  207. if maxNB==nil then maxNB=9999999 end
  208. -- Eliminate bad cases...
  209. if string.find(str, delim) == nil then
  210. return { str }
  211. end
  212. if maxNb == nil or maxNb < 1 then
  213. maxNb = 0 -- No limit
  214. end
  215. local result = {}
  216. local pat = "(.-)" .. delim .. "()"
  217. local nb = 0
  218. local lastPos
  219. for part, pos in string.gfind(str, pat) do
  220. nb = nb + 1
  221. result[nb] = part
  222. lastPos = pos
  223. if nb == maxNb then break end
  224. end
  225. -- Handle the last field
  226. if nb ~= maxNb then
  227. result[nb + 1] = string.sub(str, lastPos)
  228. end
  229. return result
  230. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement