Google app engine 我可以恢复上传到Google AppEngine的源代码吗?

Google app engine 我可以恢复上传到Google AppEngine的源代码吗?,google-app-engine,version-control,backup,Google App Engine,Version Control,Backup,我最近有一个硬盘死机,丢失了所有的源代码。是否可以提取/签出我已经上传到Google App Engine(如最新版本)的代码?不幸的是,答案是否定的。这是SO和App Engine板上常见的问题。 参见和,例如 我相信你会没事的,因为你把所有的代码都保存在源代码管理中,对吗?;) 如果您希望将来可以选择此选项,您可以在构建/部署过程中上载src的zip,并在web应用程序中的某个位置添加指向它的链接 也有类似的项目可以为您自动执行该过程。如果您使用python。。。您可以编写一个脚本,打开当前

我最近有一个硬盘死机,丢失了所有的源代码。是否可以提取/签出我已经上传到Google App Engine(如最新版本)的代码?

不幸的是,答案是否定的。这是SO和App Engine板上常见的问题。 参见和,例如

我相信你会没事的,因为你把所有的代码都保存在源代码管理中,对吗?;)

如果您希望将来可以选择此选项,您可以在构建/部署过程中上载src的zip,并在web应用程序中的某个位置添加指向它的链接


也有类似的项目可以为您自动执行该过程。

如果您使用python。。。您可以编写一个脚本,打开当前目录和子目录中的所有文件,并将它们添加到zipfile中供您下载


我对AppEngine或权限了解不多,但这似乎是可能的

,因为我刚刚费尽心思想了想如何做到这一点,我想我也可以把它作为一个答案,即使它不适用于你:

在继续之前,向你母亲的坟墓发誓,下次你将备份你的代码,或者更好,使用源代码管理。我是认真的:在我后面重复“下次我将使用源代码管理”。好的,完成后,让我们看看是否有可能为您恢复代码

如果你的应用程序是用Java编写的,恐怕你运气不好——Java应用程序的源代码甚至没有上传到AppEngine

如果您的应用程序是用Python编写的,并且定义了和处理程序,则可以通过这两个API的交互来恢复源代码。基本技巧如下:

  • 启动远程api外壳
  • 创建一个新的延迟任务,读取所有文件并将其写入数据存储
  • 等待该任务执行
  • 使用远程api从数据存储中提取数据
  • 按顺序看:

    启动远程api外壳程序 只需在命令行中键入以下内容:

    remote_api_shell.py your_app_id
    
    如果shell不在您的路径中,请在命令前面加上appenginesdk目录的路径

    将源代码写入数据存储 在这里,我们将利用这样一个事实:您已经安装了延迟处理程序,您可以使用远程api为延迟的任务排队,并且您可以延迟Python内置函数“eval”的调用

    由于“eval”只执行一条语句,而不是任意的代码块,所以我们需要将整个代码表述为一条语句,这就稍微复杂了一点。这是:

    expr = """
    [type(
        'CodeFile',
        (__import__('google.appengine.ext.db').appengine.ext.db.Expando,),
        {})(
            name=dp+'/'+fn,
            data=__import__('google.appengine.ext.db').appengine.ext.db.Text(
                open(dp + '/' + fn).read()
            )
        ).put()
     for dp, dns, fns in __import__('os').walk('.')
     for fn in fns]
    """
    
    from google.appengine.ext.deferred import defer
    defer(eval, expr)
    
    真是太棒了。让我们一次看一看:

    首先,我们使用“type”内置函数动态创建的新子类。
    type()
    的三个参数是新类的名称、父类列表和类变量的dict。表达式的前4行与此等效:

    from google.appengine.ext import db
    class CodeFile(db.Expando): pass
    
    import”的使用为解决我们不能使用语句的问题,这里有另一个解决方法:表达式
    \uuuuuuu import\uuuu('google.appengine.ext.db')
    导入引用的模块,并返回顶级模块(google)

    由于
    type()
    返回新类,我们现在有了一个Expando子类,可以用来将数据存储到数据存储中。接下来,我们调用它的构造函数,向它传递两个参数“name”和“data”。我们从当前正在处理的目录和文件的连接中构造的名称,而数据是打开该文件名并读取其内容的结果,包装在db.Text对象中,因此可以任意长。最后,我们对返回的实例调用.put(),将其存储到数据存储中

    为了读取和存储所有源文件,而不是一个文件,整个表达式发生在列表理解中,它首先迭代的结果,然后方便地返回基本目录下的所有目录和文件,然后遍历每个目录中的每个文件。这个表达式的返回值(写入数据存储的键列表)被延迟模块简单地丢弃。不过这并不重要,因为这只是我们关心的副作用

    最后,我们调用defer函数,推迟eval的调用,将刚才描述的表达式作为其参数

    读出数据 在执行上述操作并等待其完成后,我们可以再次使用远程api从数据存储中提取数据。首先,我们需要代码文件模型的本地版本:

    import os
    from google.appengine.ext import db
    class CodeFile(db.Model):
      name = db.StringProperty(required=True)
      data = db.TextProperty(required=True)
    
    现在,我们可以获取其所有实体,并将其存储到磁盘:

    for cf in CodeFile.all():
      os.makedirs(os.dirname(cf.name))
      fh = open(cf.name, "w")
      fh.write(cf.data)
      fh.close()
    
    就这样!您的本地文件系统现在应该包含您的源代码


    一个警告:下载的代码将只包含您的代码和数据文件。静态文件不包括在内,不过如果您还记得它们都是什么,您应该可以通过HTTP简单地下载它们。类似地,配置文件(如app.yaml)也不包括在内,无法恢复-您需要重写它们。不过,这比重写整个应用程序要好得多,对吧?

    更新:谷歌appengine现在允许您下载代码(用于Python、Java、PHP和Go应用程序)


    工具。

    即使在Java中,您也可以获取代码。它只需要一点逆向工程。您可以按照以下说明使用appengine SDK下载war文件:


    然后,您至少有可以通过JAD运行的类文件,以返回到源文件(至少靠近源文件)。

    发现您可以在控制台(命令行/终端)中运行以下命令。只要确保appcfg.py可以通过$PATH访问即可

    locate appcfg.py
    
    默认情况下,下面的代码打印出每个文件和下载进度

    appcfg.py download_app -A APP_ID -V VERSION_ID ~/Downloads
    

    您必须恢复到以前的sdk,
    /images/some_site_image.png
    
    <path_to_cloud_install_dir>/google-cloud-sdk/platform/google_appengine/google/appengine/tools/appcfg.py
    
    full_path = os.path.join(out_dir, path)
    
    path = re.sub(r'^/', '', path)
    
    google-cloud-sdk/platform/google_appengine/appcfg.py download_app -A <app> -V <version> 20200813t184800 <your_directory>