Last active
May 27, 2017 19:21
-
-
Save mpco/b828cd763cce110df4d9ecb15e82214d to your computer and use it in GitHub Desktop.
利用Python建立本地服务器,二维码展示想要传输的文件网址,传输完成后自动关闭服务器,并删除二维码。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: UTF-8 -*- | |
# python 2.7 | |
# request: `brew install qrencode` | |
# OS: macOS because using Applescript. | |
""" | |
Author: Mr.pc | |
Date: 20170528 | |
Version: 1.1 | |
Description: | |
利用Python建立本地服务器,二维码展示想要传输的文件网址。 | |
传输完成后自动关闭服务器,并删除二维码。 | |
如果在TIMEOUT的时间内没有进行传输,则自动关闭并删除二维码。 | |
Todo: | |
目前的版本默认只传输一次文件。 | |
在使用中,如果使用微信扫描二维码,会自动打开。 | |
这时,无法再在其他App中打开二维码中网址。 | |
""" | |
import SimpleHTTPServer | |
import SocketServer | |
import subprocess | |
import socket | |
import sys | |
import os | |
import random | |
PORT = 8000 | |
# 传输完成标记 | |
TransferCompleted = False | |
# seconds | |
TIMEOUT = 30 | |
def randomFileName(length): | |
""" | |
生成随机的文件名 | |
""" | |
return ''.join(random.choice("abcdefghijklmnopqrstuvwxyz") for i in range(length)) | |
def displayQRcode(addr, filename): | |
""" | |
生成二维码并显示 | |
""" | |
os.system("/usr/local/bin/qrencode -o '{}' '{}'".format(filename, addr)) | |
os.system("open {}".format(filename)) | |
def rmQRcode(filename): | |
""" | |
关闭二维码展示 | |
并删除二维码图片 | |
""" | |
os.system('osascript -e \'tell application "Preview" to close (every window whose name is \"' + os.path.basename(filename) + '\")\'') | |
os.system('osascript -e \'tell app "Finder" to move the POSIX file "' + filename + '" to trash\'') | |
def getLocalIP(): | |
""" | |
获取本机的局域网IP | |
""" | |
proc = subprocess.Popen("""ifconfig | grep "inet.*0xffffff00" | awk {'print $2'}""", stdout=subprocess.PIPE, shell=True) | |
(out, err) = proc.communicate() | |
return out.strip() | |
def notify(title, text): | |
""" | |
发出系统提醒 | |
""" | |
os.system(""" | |
osascript -e 'display notification "{}" with title "{}"' | |
""".format(text, title)) | |
class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): | |
def do_GET(self): | |
"""Serve a GET request.""" | |
# 限制访问的文件为指定的文件 | |
print dir(self.request) | |
if self.path == "/" + os.path.basename(sys.argv[1]): | |
f = self.send_head() | |
if f: | |
try: | |
self.copyfile(f, self.wfile) | |
finally: | |
f.close() | |
global TransferCompleted | |
TransferCompleted = True | |
print "Complete!" | |
else: | |
notify("ERROR", "want to access another file") | |
def start(): | |
class MyTCPserver(SocketServer.TCPServer): | |
# seconds | |
timeout = TIMEOUT | |
def handle_timeout(self): | |
"""Called if no new request arrives within self.timeout. | |
""" | |
print "Time out!" | |
# self.shutdown() | |
notify("TimeOut!", "") | |
rmQRcode(filename) | |
sys.exit(0) | |
httpd = MyTCPserver(("", PORT), MyHandler) | |
# print "serving at port", PORT | |
# 文件网址 | |
NetAddr = "http://{}:{}/{}".format(getLocalIP(), PORT, os.path.basename(sys.argv[1])) | |
print NetAddr | |
# 二维码文件路径 | |
filename = os.path.join(os.path.join(os.path.expanduser('~')), 'Desktop', randomFileName(5) + ".png") | |
# 生成并展示二维码 | |
displayQRcode(NetAddr, filename) | |
# httpd.serve_forever() | |
# 处理文件下载请求 | |
while not TransferCompleted: | |
print "Waiting request..." | |
httpd.handle_request() | |
# 删除二维码 | |
notify("Transfer completed!", "") | |
rmQRcode(filename) | |
if __name__ == '__main__': | |
# 将python工作目录切换至需要传输的文件所在目录 | |
# 在 macOS 的 Automator 中运行时,工作目录为当前用户~目录 | |
os.chdir(os.path.dirname(sys.argv[1])) | |
# 在 macOS 的 Automator 中运行时,sys.argv 会是 ['-c','file1', 'file1'],很奇怪 | |
# 理论上, sys.argv 中应该只有两个元素 | |
if len(sys.argv) >= 2 and os.path.isfile(sys.argv[1]): | |
while True: | |
try: | |
start() | |
except socket.error, e: | |
# 如果端口被占用,则端口+1再试 | |
if e.errno == 48: | |
PORT += 1 | |
else: | |
print "No Error!" | |
break | |
else: | |
notify("错误", "请选择一个文件!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment