Galaxy 生信平台(三):xlsx 上传与识别

我在《Firefox Quantum 向左,Google Chrome 向右中,曾经吐槽过在 Firefox 中使用 Galaxy 上传本地的 Excel 文件时,会出现 xlsx 无法识别异常的问题。今天,我们来聊一聊原因。

背景

关于 Galaxy 生物信息平台,这里就不多说了,感兴趣的可以参考本专栏的前两篇文章。

对于数据上传,Galaxy 不仅可以支持 NCBI SRA、EBI SRA、UCSC main table browser 等数据库数据的无缝对接。

30cbbbaa-5f56-4710-878b-d68e3087df8a.png

在本地文件的上传中,Galaxy 支持包括 ab1、arff、fasta、fastq、xlsx 在内 100 多种常见的格式数据上传。

b4236be1-25a3-403b-bb11-4f579a191d50.png

对于不太熟悉命令行操作的科研工作者,Excel 是他们进行批量订单提交和处理最喜欢也是最熟悉的一个数据格式,因此,我们以 Galaxy 为基础开发一部分定制化工具中,有很大的一部分都是基于 excel 文件进行处理的工具。但随之而来的问题是,所有的这些工具在 Google Chrome 下可以运行良好,但是在 Firefox 下却出现了问题。

a4be5ddb-d9ce-487f-8bec-98ef302a3d04.png

xlsx 文件上传

一开始,在办公环境下,我在内网环境部署的 Galaxy 和 https://usegalaxy.org/ 中分别对 xlsx 格式的文件进行上传测试,发现:

  • 在 Chrome 中两个 Galaxy 都能正常上传文件,没有任何错误。

  • 只有在 Firefox 中两个 Galaxy 才会出现如上截图的相同 Warning。

于是,下意识的,我开始怀疑,是不是 Firefox 会针对 Excel 的文件进行了特殊处理?还是 Galaxy 的 xlsx 文件识别存在 bug?针对前一个问题,我一开始并不知道如何去验证,但对于后一个问题,我开始了另外的尝试。

  • start_cgi_http_server.sh

#!/bin/bash

mkdir ./cgi-bin/
cp upload.cgi ./cgi-bin/
chmod +x ./cgi-bin/upload.cgi
mkdir ./upload/
python -m http.server --cgi 8080
  • upload.cgi

#!/usr/bin/python
# -*- coding: utf-8 -*-

import cgi, cgitb, os, sys

UPLOAD_DIR = './upload'

def save_uploaded_file():
    print 'Content-Type: text/html; charset=UTF-8'
    print
    print '''
<html>
<head>
  <title>Upload File</title>
</head>
<body>
'''


    form = cgi.FieldStorage()
    if not form.has_key('file'):
        print '<h1>Not found parameter: file</h1>'
        return

    form_file = form['file']
    if not form_file.file:
        print '<h1>Not found parameter: file</h1>'
        return

    if not form_file.filename:
        print '<h1>Not found parameter: file</h1>'
        return

    uploaded_file_path = os.path.join(UPLOAD_DIR, os.path.basename(form_file.filename))
    with file(uploaded_file_path, 'wb'as fout:
        while True:
            chunk = form_file.file.read(100000)
            if not chunk:
                break
            fout.write (chunk)
    print '<h1>Completed file upload</h1>'

    print '''
<hr>
<a href="../upload.html">Back to upload page</a>
</body>
</html>
'''


cgitb.enable()
save_uploaded_file()
  • upload.html

<html>
<head>
  <title>Upload File</title>
</head>
<body>
  <h1>Upload File</h1>
  <form action="cgi-bin/upload.cgi" method="POST" enctype="multipart/form-data">
    File: <input name="file" type="file">
    <input name="submit" type="submit">
  </form>
</body>
</html>
通过这三个程序,就可以在 Linux 下启动一个简单文件上传小网站。网站效果如下面的截图所示。


xlsx 文件识别

通过 python cgi 上传完文件后,在使用 python 模块进行处理的时,发现通过 Firefox 上传的文件开始出现问题了:
In [1]: import pandas as pd
In [2]: pd.read_excel("upload/upload.xlsx")
---------------------------------------------------------------------------
XLRDError                                 Traceback (most recent call last)
<ipython-input-8-9e85b7330a4e> in <module>
----> 1 pd.read_excel("upload/upload.xlsx")

......

XLRDError: Unsupported format, or corrupt file: Expected BOF record; found b'b\x14#e\xa9\x01W\x00'

于是,开始回去看 Galaxy 的源码,想要搞明白 Galaxy 对于 xlsx 文件上传到底是怎么进行识别的,终于在 packages/data/galaxy/datatypes/binary.py 中发现 Galaxy 正是使用了 python 的 zipfile 模块 :

0c7cf265-f1d4-446a-beab-a9c7713e1a2c.png
于是,我也开始使用  zipfile 来对先前 python cgi 上传的文件进行测试:
In [9]: import zipfile

In [10]: zipfile.ZipFile("upload/upload.xlsx")
---------------------------------------------------------------------------
BadZipFile                                Traceback (most recent call last)
<ipython-input-10-3793f2363956> in <module>
----> 1 zipfile.ZipFile("upload/upload.xlsx")

......

BadZipFile: File is not a zip file

同样的操作,我在 Chrome 重复了一遍,但是却神奇的发现,不管是 panda 还是 zipfile 模块,竟然一切都表现正常!似乎,Firefox 的确有点不正常。

真正原因

针对这个问题,我最开始向 Galaxy Project 团队咨询过,但一直没有从根本解决掉这个问题,他们建议考虑非 xlsx 格式数据的工具开发。

986d53e8-72f8-4f65-94ee-d4516b28efc4.jpg

直到前几天,突发奇想在 Firefox 社区中重新提起这个事情,一个热心网友的回复才让我意识到了问题的所在,也就是哈希——文件完整性校验。

d20eaf5c-1676-4440-a1a0-da20713bb38c.png

我把文件上传前的 MD5 和文件上传后的 MD5 重新进行了计算比较,这才发现:

  • 使用 Firefox 上传前后文件的 MD5 是一致,Python 却不能识别为有效的 zip 文件;

  • 使用 Chrome 上传的文件前后 MD5 是不一致的,Python 却能正常识别为有效的 zip 文件。

很明显,我的原始 xlsx 文件是有问题的!!吐血中!!!但是在办公环境中,这个原始的 xlsx 文件不管是 Office 2016 还是 WPS 都能正常打开,正常编辑保存。唯一不同的是文件中多了一个锁的标志。

3669106c-6d07-45cc-8d19-118503de119b.png

其实,这就是企业企业办公文档 Office Excel 软件加密的一种效果。

  1. 安装加密软件:安装加密服务端和管理端,客户端安装在被加密的电脑中;

  2. 设置加密策略:打开管理端,选择文件加密—加密策略,勾选需要加密的 office Excel,然后保存策略,如下图;重启被加密员工电脑。

90d0f8cb-8777-411c-a2bc-a6917273738d.jpg

测试加密效果:被加密电脑重启后,打开 word 文档,新建文档并编辑保存,保存后的文件会显示“加锁”标志,如下图示,显示已成功加密。

e312c2e9-42cb-4d5c-a227-35d4a9a49301.jpg

实现效果:员工编辑后的文档自动加密,加密后的文档未经许可,私自通过 QQ,电子邮件,U盘等任何方式传输到公司以外,都将无法打开使用;不改变编辑操作习惯,在企业内部相互流通编辑,不受影响。彻底从源头保障数据的安全性。此外还可实现如需外发文件,可通过申请解密流程授权解密后方可外发;同时还可对其他软件进行加密,比如办公软件,设计软件,工程软件,编程软件,研发软件等。

最后,把未加密的 xlsx 文件进行重新测试,一切问题迎刃而解。

总结一下

这是一个企业文档加密引发的填坑记录,从问题的发现,问题的思考,到解决的思路值得探讨记录一下。

  • MD5,MD5,MD5,重要的事情要说三遍!!!

  • 学习源码,Galaxy Project 的源码挺有意思的,不妨一读。

  • Python CGI 的一些简单应用,也挺好玩。

  • 多多交流,学会搜索,善用资源,事半功倍。

Chrome 为什么能绕开部分企业文档加密的枷锁,还原文件,这是一个有待后面学习的问题,mark 一下,同时期待大家指点迷津。

de1c88b5-c145-45b4-b75a-9a5a4c859a87.png

本文分享自微信公众号 - 生信科技爱好者(bioitee)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

posted @ 2020-01-04 20:18  章鱼猫先生  阅读(147)  评论(0编辑  收藏  举报