Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --# Notes
- --[[
- This utility backs up and restores your projects for you, by storing them as images in your Dropbox folder.
- Its features are as follows:
- 1. backs up up behind the scenes every time you change the version number
- 2. tells you how long it is since the last backup
- 3. restores your backup into a new project, tabs and all
- INSTALLING IT
- Copy this project to your Codea, named as Backup
- BACKING UP
- Include a line like this in your function setup()
- b=Backup("MyProject Ver 1.00")
- Also create a dependency to the Backup project
- (click the + at upper right of screen, find Backup on the project list, and press it)
- The utility will only back up when the string in brackets changes. It will create a new image with that name
- 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.
- RESTORING
- Create a new project to hold your restored project, and put this in function setup()
- img=readImage("Dropbox:AAA")
- r=Restore(img)
- Now change the image name to the Dropbox file you want to restore
- BEFORE YOU RUN, create a dependency to the Backup project
- (click the + at upper right of screen, find Backup on the project list, and press it)
- Now run, and when it's done, go back to the code and it should all be there.
- Ignatz version 1.00 March 2013
- --]]
- --# Main
- function setup()
- end
- --# Backup
- Backup = class()
- function Backup:init(title)
- t=readProjectData(title)
- if t~=nil then
- print("Last backup was",string.format("%.0f",os.difftime(os.time(),t)/60),"minutes ago")
- --print(os.time(),t)
- else
- self:Store(title)
- saveProjectData(title,os.time())
- end
- end
- function Backup:Store(title)
- local txt=""
- local origTxt=""
- local tabs=listProjectTabs()
- for i,t in pairs(tabs) do
- origTxt=origTxt..readProjectTab(t)
- end
- txt=origTxt..string.rep("#",10)
- local n=3-string.len(txt)%3
- if n>0 then txt=txt..string.sub("0000",1,n) end
- n=string.len(txt)
- local s=math.floor((n/3)^.5)+1
- img=image(s,s)
- local row,col=0,1
- local e={}
- local m=0
- for i=0,n-1,3 do
- for j=1,3 do
- e[j]=string.byte(string.sub(txt,i+j,i+j))
- end
- row = row + 1
- if row>s then row=1 col = col + 1 end
- img:set(col,row,e[1],e[2],e[3],255)
- end
- docName="Dropbox:"..title
- saveImage(docName,nil)
- saveImage(docName,img)
- print(title.." - backup made")
- local r=Restore(img,true)
- if origTxt==r.txt then
- print("Backup verified")
- else
- print(string.len(origTxt),string.len(txt1))
- print(string.sub(origTxt,1,500)==string.sub(txt1,1,500))
- end
- end
- --# Restore
- Restore = class()
- function Restore:init(img,test)
- --print("Recovering text")
- self.txt=self:ReadImage(img)
- --print("Text recovered")
- if self.txt=="ERROR" then
- if test~=true then print("ERROR: I couldn't read the file") end
- else
- if test~=true then s=Splitter(self.txt) end
- end
- end
- function Restore:ReadImage(img)
- if type(img)=="string" then img=readImage(img) end
- rows,cols=img.height,img.width
- t={}
- local n=0
- local r,g,b,a
- for col=1,cols do
- for row=1,rows do
- r,g,b,a=img:get(col,row)
- table.insert(t,string.char(r))
- table.insert(t,string.char(g))
- table.insert(t,string.char(b))
- n = n + 3
- end
- end
- local txt= table.concat(t)
- n=string.find(txt,string.rep("#",10))
- if n~=nil then txt=string.sub(txt,1,n-1) else txt="ERROR" end
- return txt
- end
- --# Splitter
- Splitter=class()
- --# Main
- --Main
- --[[
- CodeSplitter version 1.0 March 2013 by Ignatz
- This utility splits the class code in a project into separate tabs
- To use it, create a new project and paste all the code into the Main tab
- Put the name of the project in below and run
- --]]
- --function setup()
- -- SplitCode("Track") -- < name of your project goes in here
- --end
- function Splitter:init(txt)
- self:SplitCode(txt)
- end
- function Splitter:SplitCode(txt)
- --get total code
- --local txt=readProjectTab(nam..":Main")
- --initialise, see below
- local prevClassName,prevIndex="",1
- local str
- --it is quite difficult to find the start of a class, if you want to include
- --any preceding comments
- --this utility uses the fact that all classes end with a function, which in turn ends with "end"
- --so it splits the entire code into chunks, all of which end with a line feed followed by "end"
- local s="\nend" --the text we'll split on
- local f=split(txt,s) --split using function underneath
- for i=1,#f do --loop through chunks
- if i<#f then f[i] = f[i]..s end --the act of splitting deleted the "end" text, put it back
- c=f[i]:match("(%w+) ?= ?class") --this regex finds the class name
- if c==nil then
- local x= f[i]:find("function setup()",nil,true)
- if x~=nil then c="Main" end --this regex looks for the Main tab via setup
- end
- --if there is a classname, then the functions from here on belong to it - until we hit the
- -- next classname or the end
- --the functions preceding this chunk belong to the previous class, whose name we have cunningly
- --stored. For the first one, we have set it to Main
- if c~=nil then
- str="" --concatenate all the chunks since the previous class was written
- for j=prevIndex,i-1 do
- str=str..f[j]
- end
- str=str:match( "^%s*(.+)" ) --remove leading white space
- print("Saving",prevClassName)
- saveProjectTab(prevClassName,str) --write them to a tab
- prevClassName=trim(c)
- prevIndex=i
- end
- end
- --finish off the remaining text, which belongs to the last classname we have stored
- if prevClassName~=nil then
- str=""
- for j=prevIndex,#f do
- str=str..f[j]
- end
- str=str:match( "^%s*(.+)" ) --remove leading white spacew
- saveProjectTab(prevClassName,str)
- print("Saving",prevClassName)
- end
- print("All done!")
- end
- function trim(s)
- return s:match("^%s*(.-)%s*$")
- end
- -- Compatibility: Lua-5.0
- --http://lua-users.org/wiki/SplitJoin
- function split(str, delim, maxNb)
- if maxNB==nil then maxNB=9999999 end
- -- Eliminate bad cases...
- if string.find(str, delim) == nil then
- return { str }
- end
- if maxNb == nil or maxNb < 1 then
- maxNb = 0 -- No limit
- end
- local result = {}
- local pat = "(.-)" .. delim .. "()"
- local nb = 0
- local lastPos
- for part, pos in string.gfind(str, pat) do
- nb = nb + 1
- result[nb] = part
- lastPos = pos
- if nb == maxNb then break end
- end
- -- Handle the last field
- if nb ~= maxNb then
- result[nb + 1] = string.sub(str, lastPos)
- end
- return result
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement