Projects backup (again)

Here is another one of my attempts to backup all of my projects. I wrote something like this earlier, but you had to key in each project name to save it. I have over 300 projects, so I wasn’t about to do that. This one uses the dependency list. All you have to do before running this program is to select (check) the projects you want backed up in the dependency list. All of the checked projects will be backed up in one file that can be synced with Dropbox and to your laptop. You can also extract any project from the backup file. So I finally have all of my 300+ projects backed up on my PC and Dropbox. Here are the steps to use this code. Copy this code into the project you want. Change the line of code “projectName” to the name of your project. The reason this is done is because there isn’t any way for the code to get it’s own project name and it’s name won’t appear in the dependency list to be backed up. You also have the choice of changing the “backupName” if you want. After doing that, close the project. The reason for closing the project is because the project doesn’t exist yet for this program to read it’s own tabs and will give an error. Once you run the program, the next thing to do is long press the “Create backups” button. After creating the backup file, it will list the date and time the file was created, all of the projects that were saved, a project count and the file size. You only need to create the backup file once, or anytime you add or change projects you want saved. After that, to see a list of the projects in the backup file, long press the “Show saved projects” button. That will show the date and time of the original backup, and the projects in the file. To extract a file, either key in the project name in the “Project” area or copy it from the “Show saved projects” list and paste it into the “Project” area. Long press the “Extract” button and a message saying a tab with that name was created. You can do this multiple times if you need to extract multiple files. Once you’re done extracting the projects, close the program and each project you extracted will appear as a seperate tab. To load those projects, select and copy the code then exit the program. Long press the “Add new project” button on the Codea home page and give it a name. Press create and that project, with multiple tabs if there are any, will be created. Anytime this program is started, any tabs that were created from a previous run will be deleted. One other thing, if you get a list of “error” projects instead of “saved” projects when you create a backup, that’s because you deleted a project and it wasn’t unchecked in the dependency list first. The only way around that is to create a dummy project with that name, uncheck the dependency to it, and then delete that project. Also, any project that was extracted into a tab will be enclosed in --[[ --]] (comments). That may also cause a problem if there are already --[[ --]] within that project and you try to extract another project. Just save that project first or delete the tab. Because I use a .txt extension for the backup, you won’t see it in the Codea Dropbox folder. Just do a sync anyways and it will sync wih Dropbox. Because it’s a .txt file, you’ll be able to look at the file in Dropbox or on your PC. My 300+ projects created a backup file approx 820,000 bytes. I tried to explain everything, but if you have questions, just ask.

EDIT: Changed spritepack to assetpack in the “dds=” line of code in setup().


function setup()
    --
    -- Use the + tab (dependencies) to select the projects.
    -- Check eack project you want backed up.
    --
    projectName="backup2"    -- name of this project
    backupName="bkup.txt"    -- name of the backup file
    hardCodedBackup={projectName}
    fileSaved={}
    func=none
    projectListed=false
    dds="/Documents/Dropbox.assetpack/"
    path = os.getenv("HOME").."/Documents/"
    for a,b in pairs(listProjectTabs()) do
        if string.sub(b,1,4)~="Main" then
            saveProjectTab(b,nil)
            print("tab    "..b.." deleted.")
        end
    end
    showParams()
end

function showParams()
    parameter.action("Create backups",startBackup)  
    parameter.action("Show saved projects",startExtract)
    parameter.action("Extract",getProject)
    parameter.text("Project")
end

function startBackup()
    output.clear()
    showParams()
    dataCount=0
    bData=""
    projectTable={}
    readPlist()
    createProjTable()
    table.sort(projectTable)
    saveBackup()
    print("\
Number of projects  ",#projectTable)
    print("Number of bytes  ",dataCount)
end

function draw()
    func()    
end

function none()
end

function saveBackup()
    local tabList={}
    local data=""
    local err={}
    local file = os.getenv("HOME")..dds..backupName
    local wFd = io.open(file,"w")
    wFd:write(os.date())
    print(os.date().."\
")
    for _,name in pairs(projectTable) do
        tabList=listProjectTabs(name)
        data=""
        data=data.."\
\
[**".."[**-- "..name.."\
\
"
        if #tabList>0 then
            for _,tab in pairs(tabList) do
                data=data..string.format("\
--# %s\
",tab)
                data=data..readProjectTab(name..":"..tab)
            end
            wFd:write(data)
            dataCount = dataCount + string.len(data)
            print("saved - "..name)
        else
            table.insert(err,"error - "..name)
        end
    end
    wFd:close()
    print("\
")
    for a,b in pairs(err) do
        print(b)
    end
end

function createProjTable()
    for a,b in pairs(hardCodedBackup) do
        table.insert(projectTable,b)
    end
    local s=1
    local e,ss,s1,e1
    s,e=string.find(bData,"Dependencies",s)
    ss,ee=string.find(bData,"</array>",e)
    if s~=nil then
        while true do
            s,e=string.find(bData,"<string>",e)
            if s>ss then
                break
            end
            s1,e1=string.find(bData,"</string>",e)
            table.insert(projectTable,string.sub(bData,e+1,s1-1))
            s=e1+1
        end
    end    
end

function readPlist()
    local file = path..projectName..".codea/Info.plist"
    local bFd = io.open(file,"r")
    local data=""
    if bFd then
        while true do
            data = bFd:read(1024)
            if not data then 
                break 
            end
            bData = bData..data
        end
        bFd:close()
    end
end

function startExtract()
    output.clear()
    projectNotFound=""
    func=extractDisplay
    tab={}
    --dds="/Documents/Dropbox.spritepack/"
    listProjects()
    projectListed=true
end

function extractDisplay()
    background(40,40,50)
    fill(255)
    if #fileSaved>0 then
        text("Tabs created",WIDTH/2,HEIGHT-250)
        for a,b in pairs(fileSaved) do
            text(b,WIDTH/2,HEIGHT-250-40*a)
        end
    end
    if projectNotFound~="" then
        text("Project not found",WIDTH/2,HEIGHT-100)
        text(projectNotFound,WIDTH/2,HEIGHT-125)
    end
end

function listProjects()
    local dt=false
    local file = os.getenv("HOME")..dds..backupName
    io.input(io.open(file,"r"))
    for i in io.lines() do
        if not dt then
            print(i.."\
")
            print("*** Projects in "..backupName.." ***")
            dt=true
        end
        if string.find(i,"[**".."[**-- ",1,true) then
            print(string.sub(i,10))
        end
    end
end

function getProject() 
    if Project=="" then
        return
    end
    if not projectListed then
        output.clear()
    end
    parameter.clear()
    func=extractDisplay
    local s=string.len(Project)
    if string.sub(Project,s)=="\
" then
        Project=string.sub(Project,1,s-1)
    end
    readBackup(Project)
    showParams()
end

function readBackup(proj)
    local projectFound=false
    projectNotFound=proj
    local headerFound=false
    local file = os.getenv("HOME")..dds..backupName
    bData=""
    io.input(io.open(file,"r"))
    local str1="[**".."[**-- "
    local str2=str1..proj
    for i in io.lines() do
        if string.find(i,str1,1,true) then
            if proj==string.sub(i,10) then
                headerFound=true
                projectFound=true
                projectNotFound=""
            else
                headerFound=false
                if string.len(bData)>0 and projectFound then
                    saveProjectTab(proj,"--[====["..bData.."--]====]")
                    table.insert(fileSaved,proj)
                    projectFound=false
                    print(proj)
                    bData=""
                end 
            end           
        elseif headerFound then 
            bData=bData..i.."\
"
        end
    end
end

@Dave1707 the idea to use the dependancies plist to get the list of projects to save is brilliant!

You have 300 live projects? :open_mouth: I remove the projects I’m done with and paste them into a Pages file in case I need them again.

Also, every now and then, I connect my iPad to ITunes, go to the app tab, find Codea in the list of apps that have data (at the bottom), and just drag everything to a folder on my PC.

@dave1707 good :slight_smile:

@Ignatz I’m not on my PC very much, so I don’t bring up iTunes. I’m constantly writing programs just to see how different things work, then I end up keeping them. The hard part is finding a program I already have.

@Ignatz Got on my PC and hooked up my iPad and loaded iTunes. Went to the bottom of the apps page where file sharing is. There were 4 apps showing up for file sharing, but Codea wasn’t one of them. Maybe that’s why I never backed up any projects. I don’t remember doing anything for those 4 apps for file sharing. What am I missing. I didn’t see anything to allow Codea file sharing.

@dave1707 to get around the nested [[]] comments add a a few = between the brackets. This will not conflict with any tabs that contain [[]].

--[==========[

]==========]

@Briarfox Thanks. Even 1 = sign will work. Didn’t get any conflicts.

--[=[  
  
.....

--]=]

@dave1707 - it’s probably an iPad1 thing (or rather, iOS 5thing). Codea shows up for my ipad3

@Ignatz Thanks. Probably the iOS5 code.

I would use multiple in case the project already has a nested block comment.

@Briarfox I changed the above code to use multiple = signs. There’s still the problem with the “Add new project” button that doesn’t appear to have been fixed yet. The new project doesn’t run because of unreadable characters added to the code. Here’s the original link to the problem (towards the bottom) and a work around.

http://twolivesleft.com/Codea/Talk/discussion/comment/20477