Galaxy 生信平台(三):xlsx 上传与识别
我在《Firefox Quantum 向左,Google Chrome 向右》中,曾经吐槽过在 Firefox 中使用 Galaxy 上传本地的 Excel 文件时,会出现 xlsx 无法识别异常的问题。今天,我们来聊一聊原因。
背景
关于 Galaxy 生物信息平台,这里就不多说了,感兴趣的可以参考本专栏的前两篇文章。
对于数据上传,Galaxy 不仅可以支持 NCBI SRA、EBI SRA、UCSC main table browser 等数据库数据的无缝对接。

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

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

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 模块 :

于是,我也开始使用
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 格式数据的工具开发。

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

我把文件上传前的 MD5 和文件上传后的 MD5 重新进行了计算比较,这才发现:
使用 Firefox 上传前后文件的 MD5 是一致,Python 却不能识别为有效的 zip 文件;
使用 Chrome 上传的文件前后 MD5 是不一致的,Python 却能正常识别为有效的 zip 文件。
很明显,我的原始 xlsx 文件是有问题的!!吐血中!!!但是在办公环境中,这个原始的 xlsx 文件不管是 Office 2016 还是 WPS 都能正常打开,正常编辑保存。唯一不同的是文件中多了一个锁的标志。

其实,这就是企业企业办公文档 Office Excel 软件加密的一种效果。
安装加密软件:安装加密服务端和管理端,客户端安装在被加密的电脑中;
设置加密策略:打开管理端,选择文件加密—加密策略,勾选需要加密的 office Excel,然后保存策略,如下图;重启被加密员工电脑。

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

实现效果:员工编辑后的文档自动加密,加密后的文档未经许可,私自通过 QQ,电子邮件,U盘等任何方式传输到公司以外,都将无法打开使用;不改变编辑操作习惯,在企业内部相互流通编辑,不受影响。彻底从源头保障数据的安全性。此外还可实现如需外发文件,可通过申请解密流程授权解密后方可外发;同时还可对其他软件进行加密,比如办公软件,设计软件,工程软件,编程软件,研发软件等。
最后,把未加密的 xlsx 文件进行重新测试,一切问题迎刃而解。
总结一下
这是一个企业文档加密引发的填坑记录,从问题的发现,问题的思考,到解决的思路值得探讨记录一下。
MD5,MD5,MD5,重要的事情要说三遍!!!
学习源码,Galaxy Project 的源码挺有意思的,不妨一读。
Python CGI 的一些简单应用,也挺好玩。
多多交流,学会搜索,善用资源,事半功倍。
Chrome 为什么能绕开部分企业文档加密的枷锁,还原文件,这是一个有待后面学习的问题,mark 一下,同时期待大家指点迷津。

本文分享自微信公众号 - 生信科技爱好者(bioitee)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
Galaxy 生信平台(三):xlsx 上传与识别的更多相关文章
- SNF开发平台WinForm之六-上传下载组件使用-SNF快速开发平台3.3-Spring.Net.Framework
6.1运行效果: 6.2开发实现: 1.先在要使用的项目进行引用,SNF.WinForm.Attachments.dll文件. 2.在工具箱内新建选项卡->选择项,浏览找到文件SNF.WinFo ...
- 解决Windows平台通过cURL上传APP到蒲公英pgyer平台时无法使用中文升级描述的问题
解决Windows平台通过cURL上传APP到蒲公英pgyer平台时无法使用中文升级描述的问题 官方上传命令 curl -F file=@"315.apk" -F uKey=XXX ...
- 三种上传文件不刷新页面的方法讨论:iframe/FormData/FileReader
发请求有两种方式,一种是用ajax,另一种是用form提交,默认的form提交如果不做处理的话,会使页面重定向.以一个简单的demo做说明: html如下所示,请求的路径action为"up ...
- 三 : spring-uploadify上传文件
一 : applicationContext.xml中:必须声明不然获取不到<!-- 上传文件的配置 --> <bean id="multipartResolver&quo ...
- upload三种上传方式(上)---Servlet---post---commons-fileupload.1.2.1.jar方式请求上传文件
上传前进行的配置选项: 1.在下方的Servers中,右键你的tomcat--open,选中下面两个配置. 第一个:Serve modules without publishing 作用:tomcat ...
- Windows操作系统远程Linux服务器传输文件方法(以EasyDSS云平台、EasyNVR上传部署为例)
本文转自博客:https://blog.csdn.net/black_3717/article/details/79769406 问题背景: 之前给客户部署我们一款EasyDSS云平台(配合EasyN ...
- jQuery插件之路(三)——文件上传(支持拖拽上传)
好了,这次咱一改往日的作风,就不多说废话了,哈哈.先贴上源代码地址,点击获取.然后直接进入主题啦,当然,如果你觉得我有哪里写的不对或者欠妥的地方,欢迎留言指出.在附上一些代码之前,我们还是先来了解下, ...
- web自动化之selenium(三)文件上传
1.上传标签为input #若上传文件的标签为<input>可以直接定位标签,然后send_keys(文件路径)可以直接上传 2.利用第三方软件Autoit上传 1.下载Autoit:ht ...
- SpringBoot2.0(三) 文件上传
SpringBoot中发起文件上传示例: /** * 文件上传 * @param multipartFile * @param path * @return */ @RequestMapping(va ...
- Struts2学习(三)上传下载
今天记录一下利用struts2实现上传下载,借此案例说明一下struts2的开发流程. 须要注意的是struts2版本号不同非常多地方的写法是不同的.本例使用struts2.3.15 .有差别的地方文 ...
随机推荐
- CF1801B题解
CF1801B题解 传送门 更好的阅读体验 简化题意:有 n 个商店,每个商店卖 a,b 两种商品,价格分别为 \(a_i,b_i\),你需要在每个商店买一个商品,并且不能在所有商店都买同一种商品,最 ...
- 【故障公告】数据库服务器 CPU 近 100% 造成全站故障,雪上加霜难上加难的三月
数据库服务器 CPU 近 100% 问题几乎每年都要发生一次,上次发生在去年1月31日,每次都是通过主备切换或者重启实例解决,数据库服务用的是阿里云 RDS SQL Server 2016 标准版. ...
- 一连串div跟随鼠标移动
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- [JAVA/Maven/IDEA]解决JAR包冲突
1 前言 想必这个问题,诸多同仁都遇到过. 很不凑巧,这段时间咱也屡次撞上这问题好几次了. 因此,实在是有必要说说怎么解决好这问题了0.0 2 诊断:包冲突的异常信息特征 [类定义未发现错误] NoC ...
- odoo 开发入门教程系列-约束(Constraints)
约束(Constraints) 上一章介绍了向模型中添加一些业务逻辑的能力.我们现在可以将按钮链接到业务代码,但如何防止用户输入错误的数据?例如,在我们的房地产模块中,没有什么可以阻止用户设置负预期价 ...
- dev-tools
Maven配置依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId& ...
- Android 为什么事件分发的入口函数是dispatchTouchEvent
参考:https://xiaozhuanlan.com/topic/8946537021 从触摸屏幕到事件在底层传输最终会到: private int processPointerEvent(Queu ...
- Buffer中的public void write(Buffer source, long byteCount)解析
这个把source缓冲区中的数据写到当前缓冲区的方法是比较经典的: if (source == null) throw new IllegalArgumentException("sourc ...
- 基于Python的爬虫案例
案例1:使用爬虫爬取京东华为手机用户评论 本案例借鉴哔哩哔哩博客主视频教程,感谢其教程为我开启了爬虫之旅:https://www.bilibili.com/video/BV1Yt4y1Y7nt?t=3 ...
- 在CentOS上安装与卸载Docker Engine
本文参考Docker官网提供的 安装手册编写 测试使用的操作系统版本为CentOS 7.9 安装Docker Engine 要在 CentOS 上开始使用 Docker 引擎,请确保 满足先决条件,然 ...