Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Backing up projects

in General Posts: 2

When I lost my iPad, I also lost all of my projects. Is there a way to backup projects onto another device or in the cloud?

Tagged:

Comments

  • Posts: 1,351
    @glwhart - there are a number of ways to back up. Using an external filing app or internally running the Codea backup facility from the main Codea system window. Also @dave1707 has written a number of project and project library backup projects. You can save each file as a zip file from the system backup options. Just check it out before you program further. You obviously need a storage option such as Dropbox to store them in.
  • AnatolyAnatoly Mod
    Posts: 870

    If you lost your iPad, there’s not much you can do. If the iPad is brocken, you could still try to get it’s memory back.

  • edited November 2 Posts: 2

    @Bri_G I have dropbox and google drive so I could backup to one of those. Being somewhat new to Codea, I'm not sure how to do what you suggest. Could you offer step by step instructions for one of your proposed solutions? For example, I don't know what you mean by "the main Codea system window".

  • AnatolyAnatoly Mod
    Posts: 870

    The easiest way is to hold on a project, three options will pop out. Select Copy Project Code and post it on pastebin/github, and on the other iPad run the installer.

    local linkRawCode = "INSERT LINK TO WHERE YOUR CODE IS"
    
    local function success(data)
        if data:find("%-%-%# Main") then --paste-into-project format
            data = data.."--# " --add new file tag to end in order to capture last file
            for name, file in data:gmatch("(%w+)\n(.-)\n%-%-%# ") do --capture each name and file
                saveProjectTab(name, file)
                print("Saved", name)
            end
        else --put it all in one tab
            saveProjectTab("Main", data)
        end
        load(data)() --load the file
        setup() --run it
    end
    
    local function failure(error)
        print("Error", error)
    end
    
    http.request(linkRawCode, success, failure)
    
  • edited November 2 Posts: 1,351

    @glwhart - there have been many posts on using Dropbox for backup of files. I'll try to cover this .On the root of Dropbox there is a folder called Apps (on mine) within that folder any external package (Codea in this case) can add a package root folder - so I have a Codea folder there. You can add any other folders/files in that folder. Most files there will be visible to Codea provided they have a recognised file type. Files in folders will not be visible but can still be accessed if you use an absolute address.

    Codea keeps a duplicate copy of visible files in the Codea root on your iPad. This is accessible via the Asserts option from the top left button on the Codea main window. When you change the Dropbox folder contents (remote) you need to sync the iPad Dropbox folder from the top menu in the Codea root folder.

    Try it out and if you have problems we can guide you through it.

  • AnatolyAnatoly Mod
    Posts: 870

    I know it's a bit outdated, but still, the old wiki tells, that, "[a]t the moment, there is not an elegant answer to copying code to and from Codea.". But you can try doing all the options presented above (or below) this post.
    Personally I was fine with storing all the code in a hub like pastebin, and then just re-downloading the code this way.

  • dave1707dave1707 Mod
    Posts: 7,836

    Here’s my latest backup/restore program. It created a backup file of my 578 projects in less than a second. Once you create a backup file, you can restore all or selected projects. This saves the backup file in the Codea Dropbox folder where you can then sync it with the Dropbox app. When I got a new iPad, I synced the new iPad with the Dropbox app to get the backup file into the Codea Dropbox folder on the new iPad. I then emailed a copy of the backup project, which should be saved separately, from my old iPad to the new one. I selected restore all projects and unselected the backup project name. You can't restore a running project or you’ll get a Codea error and the restore will stop. It took about a second or so to create my 578 Codea projects on the new iPad.

    When the backup is run, it creates a backup file named bkAyymmdd-hhmm where yymmdd is the year, month, day and hhmm is the hour and minute that the file was created. You can do backups as often as you want as long as you wait at least a minute.

    This only saves the Codea projects. If you have assets or images or anything other than the project, those aren’t saved.

    I’ve used various versions of this code to save and restore projects thru the years. The only time it crashed was when I tried to restore the backup project which you can’t do. You can’t restore a running project. I did that just to see what would happen.

    displayMode(FULLSCREEN)
    
    function setup()
        delay=5
        pns="PROJ".."NAME".."START" -- project name start
        pne="PROJ".."NAME".."END"   -- project name end
        tns="TAB".."NAME".."START"  -- tab name start
        tne="TAB".."NAME".."END"    -- tab name end
        te="TAB".."END"             -- tab end
        pe="PROJ".."END"            -- project end
        bk1,bk2,bk3,bk4="","","",""
        msg1=""
        m1=button(WIDTH/2,HEIGHT-100,200,50,"Create a backup",createBkup)
        m2=button(WIDTH/2,HEIGHT-200,200,50,"Select a backup",getBkups)
        m3=button(WIDTH/2,HEIGHT-300,200,50,"Exit",exit)
        b1=button(190,HEIGHT-200,180,50,"Turn all projects on.",allOn)
        b2=button(190,HEIGHT-260,180,50,"Turn all projects off.",allOff)
        b3=button(190,HEIGHT-360,180,50,"Allow overwrite. OFF",allowOverwrite)
        b5=button(190,HEIGHT-520,180,50,"Restore selected items",restore)
        b6=button(190,100,180,50,"Return to menu",retn)
        func=menu
    end
    
    function draw()
        background(40, 40, 50)
        func()
    end
    
    function touched(t)
        if t.state==ENDED then
            if func==menu then
                m1:touched(t)
                m2:touched(t)
                m3:touched(t)
            elseif func==showBkups then
                for a,b in pairs(bkupTab) do
                    if math.abs(t.x-WIDTH/2)<100 and math.abs(t.y-(HEIGHT-a*75+dy))<25 then
                        selectedBackupFile=b
                        func=getProjects
                    end
                end
                b6:touched(t)
            elseif func==showProjects then
                for a,b in pairs(projTab) do
                    if math.abs(t.x-WIDTH/2)<100 and math.abs(t.y-(HEIGHT-a*75+dy))<25 then
                        b.sel=not b.sel
                    end
                end
                b1:touched(t)
                b2:touched(t)
                b3:touched(t)
                b5:touched(t)
                b6:touched(t)
            elseif func==showRestoreTable then
                b6:touched(t)
            end
        end
        if t.state==MOVING then
            if func==showProjects or func==showRestoreTable then
                if t.x<100 or t.x>WIDTH-100 then
                    sp=1
                    if t.y<HEIGHT/2 then
                        sp=20
                    end
                    dy=dy+t.deltaY*sp
                    if dy<0 then
                        dy=0
                    end
                end
            end
        end
    end
    
    function menu()
        fill(255)
        m1:draw()
        m2:draw()
        m3:draw()
        text(bk1,WIDTH/2,300)
        text(bk2,WIDTH/2,260)
        text(bk3,WIDTH/2,220)
        text(bk4,WIDTH/2,180)
    end
    
    function exit()
        close()
    end
    
    function retn()
        msg1=""
        func=menu
    end
    
    function createBkup()
        if delay>0 then
            func=createBkup
            text("Creating backup",WIDTH/2,HEIGHT/2)
            delay=delay-1
            return
        end
        local proj=listProjects("Documents")
        local t=os.date("*t")
        backupName=string.format("bkA%02d%02d%02d-%02d%02d",
        t.year%100,t.month,t.day,t.hour,t.min)
        local temp={}
        local dt=os.date()
        local cnt=0
        table.insert(temp,"BKUP==START.."..dt)
        for a,b in pairs(proj) do
            lst=listProjectTabs(b)
            cnt=cnt+1
            table.insert(temp,pns.."=="..b.."=="..pne)
            for c,d in pairs(lst) do
                table.insert(temp,tns.."=="..d.."=="..tne)
                table.insert(temp,readProjectTab(b..":"..d))
                table.insert(temp,"=="..te)
            end
            table.insert(temp,"=="..pe)
        end
        table.insert(temp,"BKUP==END")
        local str=table.concat(temp,"\n")
        bk1=backupName
        bk2=dt
        bk3="Projects saved = "..cnt
        bk4="File size = "..#str.." bytes"
        saveText("Dropbox:"..backupName,str)
        delay=5
        func=menu
    end
    
    function getBkups()
        bk1,bk2,bk3,bk4="","","",""
        bkupTab={}
        showBackupTable=true
        dy=0
        local lst=assetList("Dropbox")
        table.sort(lst)
        for a,b in pairs(lst) do
            if string.find(b,"bk") then
                table.insert(bkupTab,b)
            end
        end
        func=showBkups
    end
    
    function showBkups()
        for a,b in pairs(bkupTab) do
            sprite("Cargo Bot:Dialogue Button",WIDTH/2,HEIGHT-a*75+dy,200,50)
            text(b,WIDTH/2,HEIGHT-a*75+dy)
        end
        b6:draw()
    end
    
    function getProjects()
        text("Please wait, getting a list of all projects",WIDTH/2,HEIGHT/2)
        projTab={}
        local name=selectedBackupFile
        bkupFile=readText("Dropbox:"..name)
        if bkupFile==nil then
            alert("No backup file selected.","ERROR")
            return
        end
        local sss=pns.."==(.-)=="..pne
        for projName,proj in string.gmatch(bkupFile,sss) do
            table.insert(projTab,{proj=projName,sel=false,res=""})
        end
        dy=0
        func=showProjects
    end
    
    function showProjects()
        text("Tap a project to select or unselect it.",WIDTH/2,HEIGHT-20+dy)
        for a,b in pairs(projTab) do
            tint(255)
            if b.sel then
                tint(0, 255, 0, 255)
            end
            sprite("Cargo Bot:Dialogue Button",WIDTH/2,HEIGHT-a*75+dy,200,50)
            fill(255)
            text(b.proj,WIDTH/2,HEIGHT-a*75+dy)
            if b.res~="" then
                sprite("Cargo Bot:Dialogue Button",575,HEIGHT-a*75+dy,150,50)
                text(b.res,575,HEIGHT-a*75+dy)
            end
        end
        tint(255)
        b1:draw()
        b2:draw()
        b3:draw()
        b5:draw()
        b6:draw()
        scrollArea()
        text(msg1,200,200)
    end
    
    function scrollArea()
        fill(97, 229, 165, 100)
        rect(0,HEIGHT/2+20,100,HEIGHT)
        rect(0,0,100,HEIGHT/2-20)
        rect(WIDTH-100,HEIGHT/2+20,100,HEIGHT)
        rect(WIDTH-100,0,100,HEIGHT/2-20)
        fill(255)
        text("SLOW\nSCROLL\nAREA",50,HEIGHT*.75)
        text("FAST\nSCROLL\nAREA",50,HEIGHT*.25)
        text("SLOW\nSCROLL\nAREA",WIDTH-50,HEIGHT*.75)
        text("FAST\nSCROLL\nAREA",WIDTH-50,HEIGHT*.25)
    end
    
    function allOn()
        for a,b in pairs(projTab) do
            b.sel=true
        end
    end
    
    function allOff()
        for a,b in pairs(projTab) do
            b.sel=falss
        end
    end
    
    function allowOverwrite(self)
        Allow_overwrite=not Allow_overwrite
        if Allow_overwrite then
            self.name="Allow overwrite.  ON"
            self.col=color(255,0,0)
        else
            self.name="Allow overwrite.  OFF"
            self.col=color(255)
        end
    end
    
    function restore()
        resTab={}
        msg1=""
        if projTab==nil or selectedBackupFile=="" then
            alert("No projects selected.","ERROR")
            return
        end
        dy=0
        cnt=0
        for a,b in pairs(projTab) do
            if b.sel then
                cnt=cnt+1
                pname=b.proj
                restoreProject()
            end
        end
        if cnt>0 then
            alert("Check for error messages.","RESTORE COMPLETE")
        else
            alert("Nothing selected for restore.","ERROR")
            return
        end
        allOff()
        if Allow_overwrite then
            allowOverwrite(b3)
        end
        dy=0
        func=showRestoreTable
    end
    
    function restoreProject()
        name=pname
        local sss=pns.."==(.-)=="..pne.."\n(.-)=="..pe
        if hasProject(name) then
            if Allow_overwrite then
                deleteProject(name)
            else
                table.insert(resTab,{proj=name,res="Overwrite   OFF"})
                return
            end
        end
        if not hasProject(name) then
            createProject(name)
            for projName,proj in string.gmatch(bkupFile,sss) do
                if name==projName then
                    getTab(proj)
                end
            end
            table.insert(resTab,{proj=name,res="Restored"})
        end
    end
    
    function getTab(proj)
        local sss=tns.."==(%g+)=="..tne.."\n(.-)\n=="..te
        for tabName,tab in string.gmatch(proj,sss) do
            saveProjectTab(name..":"..tabName,tab)
        end
    end
    
    function showRestoreTable()
        for a,b in pairs(resTab) do
            sprite("Cargo Bot:Dialogue Button",400,HEIGHT-a*75+dy,200,50)
            fill(255)
            text(b.proj,400,HEIGHT-a*75+dy)
            sprite("Cargo Bot:Dialogue Button",575,HEIGHT-a*75+dy,150,50)
            text(b.res,575,HEIGHT-a*75+dy)
        end
        b6:draw()
        scrollArea()
    end
    
    button=class()
    
    function button:init(x,y,w,h,n,f)
        self.x=x
        self.y=y
        self.w=w
        self.h=h
        self.name=n
        self.func=f
        self.col=color(255)
    end
    
    function button:draw()
        sprite("Cargo Bot:Dialogue Button",self.x,self.y,self.w,self.h)
        fill(self.col)
        text(self.name,self.x,self.y)
    end
    
    function button:touched(t)
        if math.abs(t.x-self.x)<self.w/2 and math.abs(t.y-self.y)<self.h/2 then
            self.func(self)
        end
    end
    
  • Posts: 1,351

    @glwhart - I can vouch for the backup system that @dave1707 has developed. I have been using this for a few months. The options are improving all the time, the selected project menu that @Anatoly describes is very new and I have used several times for backing up individual files. I suggest you try them all to see which you prefer.

  • AnatolyAnatoly Mod
    Posts: 870

    I've created a Wiki Article on this. Read in the link attached below.

    https://codea.fandom.com/wiki/Installer_Code

Sign In or Register to comment.