liangshitang
5 years ago
7 changed files with 278 additions and 143 deletions
-
4.gitignore
-
7.htaccess
-
12
-
32LICENSE.txt
-
52README.md
-
47composer.json
-
278git_ftp.py
@ -1,4 +0,0 @@ |
|||||
# Compiled Object files, Static and Dynamic libs (Shared Objects) |
|
||||
.idea |
|
||||
composer.lock |
|
||||
1111 |
|
@ -1,7 +0,0 @@ |
|||||
<IfModule mod_rewrite.c> |
|
||||
Options +FollowSymlinks |
|
||||
RewriteEngine On |
|
||||
RewriteCond %{REQUEST_FILENAME} / [NC] |
|
||||
RewriteCond %{REQUEST_FILENAME} !-f |
|
||||
RewriteRule ^(.*)$ /public/index.php/$1 [QSA,PT,L] |
|
||||
</IfModule> |
|
@ -1 +0,0 @@ |
|||||
232323 |
|
@ -1,32 +0,0 @@ |
|||||
|
|
||||
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 |
|
||||
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn) |
|
||||
All rights reserved。 |
|
||||
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 |
|
||||
|
|
||||
Apache Licence是著名的非盈利开源组织Apache采用的协议。 |
|
||||
该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, |
|
||||
允许代码修改,再作为开源或商业软件发布。需要满足 |
|
||||
的条件: |
|
||||
1. 需要给代码的用户一份Apache Licence ; |
|
||||
2. 如果你修改了代码,需要在被修改的文件中说明; |
|
||||
3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 |
|
||||
带有原来代码中的协议,商标,专利声明和其他原来作者规 |
|
||||
定需要包含的说明; |
|
||||
4. 如果再发布的产品中包含一个Notice文件,则在Notice文 |
|
||||
件中需要带有本协议内容。你可以在Notice中增加自己的 |
|
||||
许可,但不可以表现为对Apache Licence构成更改。 |
|
||||
具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 |
|
||||
|
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
||||
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
POSSIBILITY OF SUCH DAMAGE. |
|
@ -1,52 +0,0 @@ |
|||||
ThinkPHP 6.0 |
|
||||
=============== |
|
||||
|
|
||||
> 运行环境要求PHP7.1+。 |
|
||||
|
|
||||
## 主要新特性 |
|
||||
|
|
||||
* 采用`PHP7`强类型(严格模式) |
|
||||
* 支持更多的`PSR`规范 |
|
||||
* 原生多应用支持 |
|
||||
* 更强大和易用的查询 |
|
||||
* 全新的事件系统 |
|
||||
* 模型事件和数据库事件统一纳入事件系统 |
|
||||
* 模板引擎分离出核心 |
|
||||
* 内部功能中间件化 |
|
||||
* SESSION/Cookie机制改进 |
|
||||
* 对Swoole以及协程支持改进 |
|
||||
* 对IDE更加友好 |
|
||||
* 统一和精简大量用法 |
|
||||
|
|
||||
## 安装 |
|
||||
|
|
||||
~~~ |
|
||||
composer create-project topthink/think tp 6.0.*-dev |
|
||||
~~~ |
|
||||
|
|
||||
如果需要更新框架使用 |
|
||||
~~~ |
|
||||
composer update topthink/framework |
|
||||
~~~ |
|
||||
|
|
||||
## 文档 |
|
||||
|
|
||||
[完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content) |
|
||||
|
|
||||
## 参与开发 |
|
||||
|
|
||||
请参阅 [ThinkPHP 核心框架包](https://github.com/top-think/framework)。 |
|
||||
|
|
||||
## 版权信息 |
|
||||
|
|
||||
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。 |
|
||||
|
|
||||
本项目包含的第三方源码和二进制文件之版权信息另行标注。 |
|
||||
|
|
||||
版权所有Copyright © 2006-2019 by ThinkPHP (http://thinkphp.cn) |
|
||||
|
|
||||
All rights reserved。 |
|
||||
|
|
||||
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。 |
|
||||
|
|
||||
更多细节参阅 [LICENSE.txt](LICENSE.txt) |
|
@ -1,47 +0,0 @@ |
|||||
{ |
|
||||
"name": "topthink/think", |
|
||||
"description": "the new thinkphp framework", |
|
||||
"type": "project", |
|
||||
"keywords": [ |
|
||||
"framework", |
|
||||
"thinkphp", |
|
||||
"ORM" |
|
||||
], |
|
||||
"homepage": "http://thinkphp.cn/", |
|
||||
"license": "Apache-2.0", |
|
||||
"authors": [ |
|
||||
{ |
|
||||
"name": "liu21st", |
|
||||
"email": "liu21st@gmail.com" |
|
||||
} |
|
||||
], |
|
||||
"require": { |
|
||||
"php": ">=7.1.0", |
|
||||
"topthink/framework": "6.0.*-dev", |
|
||||
"topthink/think-orm": "2.0.*-dev", |
|
||||
"topthink/think-view": "^1.0", |
|
||||
"phpoffice/phpword": "^0.16.0", |
|
||||
"ext-json": "*", |
|
||||
"ext-curl": "*" |
|
||||
}, |
|
||||
"require-dev": { |
|
||||
"symfony/var-dumper": "^4.2" |
|
||||
}, |
|
||||
"autoload": { |
|
||||
"psr-4": { |
|
||||
"app\\": "app" |
|
||||
}, |
|
||||
"psr-0": { |
|
||||
"": "extend/" |
|
||||
} |
|
||||
}, |
|
||||
"config": { |
|
||||
"preferred-install": "dist" |
|
||||
}, |
|
||||
"scripts": { |
|
||||
"post-autoload-dump": [ |
|
||||
"@php think service:discover", |
|
||||
"@php think vendor:publish" |
|
||||
] |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,278 @@ |
|||||
|
import configparser |
||||
|
import getopt |
||||
|
import os |
||||
|
import sys |
||||
|
from ftplib import FTP, error_perm |
||||
|
import git |
||||
|
|
||||
|
|
||||
|
class GitUtil(object): |
||||
|
user = None |
||||
|
passwd = None |
||||
|
git_url = None |
||||
|
dir_name = None |
||||
|
repo = git.Repo |
||||
|
|
||||
|
def __init__(self, **kwargs): |
||||
|
user = kwargs.pop("user") |
||||
|
passwd = kwargs.pop("passwd") |
||||
|
git_url = kwargs.pop("git_url") |
||||
|
if passwd and user and git_url: |
||||
|
self.passwd = passwd |
||||
|
self.user = user |
||||
|
git_url = str(git_url).replace("http://", "") |
||||
|
self.dir_name = git_url.split("/")[-1].split(".")[0] |
||||
|
self.git_url = git_url |
||||
|
else: |
||||
|
raise Exception("(user,passwd,git_url)必须全部传") |
||||
|
|
||||
|
self.__user_login() |
||||
|
|
||||
|
def __user_login(self): |
||||
|
temp_dir = os.getenv('TEMP') + "/" + self.dir_name |
||||
|
if os.path.exists(temp_dir + "/" + ".git"): |
||||
|
self.repo = git.Repo.init(temp_dir) |
||||
|
# 强制更新最新代码 覆盖本地的 |
||||
|
self.repo.git.execute('git reset --hard origin/master') |
||||
|
print("git目录已经存在!") |
||||
|
return |
||||
|
try: |
||||
|
self.repo = git.Repo.clone_from("http://%s:%s@%s" % (self.user, self.passwd, self.git_url), |
||||
|
to_path=temp_dir) |
||||
|
print("克隆成功!") |
||||
|
except Exception as e: |
||||
|
raise Exception("克隆出错:%s" % e.args) |
||||
|
|
||||
|
def get_diff_file(self, old_version): |
||||
|
new_version = self.get_current_version() |
||||
|
resp = self.repo.git.execute("git diff -no-pager --name-only %s %s" % (old_version, new_version)) |
||||
|
if len(resp) is 0: |
||||
|
return None |
||||
|
return resp.split("\n") |
||||
|
|
||||
|
def get_current_version(self): |
||||
|
return self.repo.head.log_entry(-1).newhexsha |
||||
|
|
||||
|
|
||||
|
class FtpUtil(object): |
||||
|
ftp = FTP() |
||||
|
log = "" |
||||
|
list_name = [] |
||||
|
dict_dir = {} |
||||
|
cur_dir = "" |
||||
|
|
||||
|
def __init__(self, host, user, pwd, port=21): |
||||
|
self.ftp.connect(host=host, port=port) |
||||
|
self.ftp.login(user=user, passwd=pwd) |
||||
|
self.ftp.set_pasv(False) |
||||
|
|
||||
|
def get_remote_name(self, line): |
||||
|
file_name = str(line).split(" ")[-1] |
||||
|
if file_name not in [".", ".."]: |
||||
|
type_file = line[0] |
||||
|
self.dict_dir[self.cur_dir].append([type_file, file_name]) |
||||
|
|
||||
|
def remote_local_same(self, remote_path, local_path): |
||||
|
try: |
||||
|
remote_size = self.ftp.size(remote_path) |
||||
|
except Exception as e: |
||||
|
remote_size = -1 |
||||
|
try: |
||||
|
local_size = os.path.getsize(local_path) |
||||
|
except Exception as e: |
||||
|
local_size = -1 |
||||
|
print("ftp目录的文件【%s】大小为【%s】" % (remote_path, remote_size)) |
||||
|
print("本地目录的文件【%s】大小为【%s】" % (local_path, local_size)) |
||||
|
print("------------------------------------") |
||||
|
if remote_size == local_size: |
||||
|
return 1 |
||||
|
else: |
||||
|
return 0 |
||||
|
|
||||
|
def down_file(self, remote_path, local_path): |
||||
|
if not self.remote_local_same(remote_path, local_path): |
||||
|
if not os.path.exists(os.path.dirname(local_path)): |
||||
|
os.makedirs(os.path.dirname(local_path)) |
||||
|
local_fp = open(local_path, 'wb') |
||||
|
self.ftp.retrbinary("RETR " + remote_path, local_fp.write) |
||||
|
local_fp.close() |
||||
|
|
||||
|
def down_files(self, remote_path, local_path): |
||||
|
try: |
||||
|
self.ftp.cwd(remote_path) |
||||
|
except error_perm as e: |
||||
|
return |
||||
|
print("------------------------------------") |
||||
|
print("ftp目录切换到:%s" % self.ftp.pwd()) |
||||
|
try: |
||||
|
self.cur_dir = self.ftp.pwd() |
||||
|
self.dict_dir[self.cur_dir] = [] |
||||
|
self.ftp.dir(self.get_remote_name) |
||||
|
for i in self.dict_dir[self.ftp.pwd()]: |
||||
|
local_ = os.path.join(local_path, i[1]) |
||||
|
if i[0] == "-": |
||||
|
self.down_file(i[1], local_) |
||||
|
elif i[0] == "d": |
||||
|
self.down_files(i[1], local_) |
||||
|
self.ftp.cwd('..') |
||||
|
except Exception as e: |
||||
|
print("超时ing......。正在重新连接!") |
||||
|
self.down_files("./", "./") |
||||
|
self.list_name = [] |
||||
|
self.dict_dir = {} |
||||
|
self.cur_dir = "" |
||||
|
print("回到目录【%s】" % self.ftp.pwd()) |
||||
|
print("------------------------------------") |
||||
|
|
||||
|
def read_version_file(self): |
||||
|
self.ftp.cwd("/") |
||||
|
fp = open("./.version", "wb") |
||||
|
try: |
||||
|
self.ftp.retrbinary("RETR .version", fp.write) |
||||
|
except error_perm as e: |
||||
|
if "550" in e.__str__(): |
||||
|
return 0 |
||||
|
finally: |
||||
|
fp.close() |
||||
|
if os.path.getsize("./.version") == 0: |
||||
|
return 0 |
||||
|
return 1 |
||||
|
|
||||
|
def upload_file(self, local_path, remote_path): |
||||
|
print("-----------------------") |
||||
|
print("即将上传的文件为:【%s】" % local_path) |
||||
|
self.ftp.cwd("/") |
||||
|
fp = open(local_path, "rb") |
||||
|
buf_size = 1024 |
||||
|
try: |
||||
|
self.ftp.storbinary("STOR %s" % remote_path, fp, buf_size) |
||||
|
print("文件为:【%s】" % local_path, "已经上传成功!") |
||||
|
except error_perm as e: |
||||
|
print("出错文件:【%s】" % remote_path + "\r\n", "出错原因:【%s】" % e.args) |
||||
|
finally: |
||||
|
fp.close() |
||||
|
print("-------------------------------------") |
||||
|
|
||||
|
|
||||
|
def init_config(): |
||||
|
try: |
||||
|
opts, args = getopt.getopt(sys.argv[1:], "hf:", ["file="]) |
||||
|
if not opts: |
||||
|
if os.path.exists("./.ftp_git.ini"): |
||||
|
opts = [('-f', ".ftp_git.ini")] |
||||
|
except getopt.GetoptError: |
||||
|
print(sys.argv[0] + ' -f 配置文件路径') |
||||
|
sys.exit(2) |
||||
|
for opt, arg in opts: |
||||
|
if opt in ("-h", "--help"): |
||||
|
print(sys.argv[0] + ' -f 配置文件路径') |
||||
|
print(""" |
||||
|
配置文件格式如下: |
||||
|
[ftp] |
||||
|
user = 用户账号 |
||||
|
passwd = 密码 |
||||
|
host = ip地址 |
||||
|
port = 端口号默认21 |
||||
|
[git] |
||||
|
user = 登录账号 |
||||
|
passwd = 密码 |
||||
|
url = 仓库地址 |
||||
|
""") |
||||
|
sys.exit() |
||||
|
elif opt in ("-f", "--file"): |
||||
|
cf = configparser.ConfigParser() |
||||
|
try: |
||||
|
cf.read(arg, encoding='gbk') |
||||
|
ftp_user = cf.get("ftp", "user") |
||||
|
ftp_passwd = cf.get("ftp", "passwd") |
||||
|
host = cf.get("ftp", "host") |
||||
|
port = cf.get("ftp", "port") |
||||
|
|
||||
|
git_user = cf.get("git", "user") |
||||
|
git_passwd = cf.get("git", "passwd") |
||||
|
url = cf.get("git", "url") |
||||
|
except configparser.NoSectionError as s: |
||||
|
print("请在配置文件中配置:[%s]节点" % s.section) |
||||
|
sys.exit() |
||||
|
except configparser.NoOptionError as e: |
||||
|
print("请在[%s]节点中配置:%s 选项" % (e.section, e.option)) |
||||
|
sys.exit() |
||||
|
if not opts: |
||||
|
print("开始配置ftp信息") |
||||
|
ftp_user = input("请输入ftp登录账号:") |
||||
|
while not ftp_user: |
||||
|
ftp_user = input("ftp登录账号不能为空(重新输入):") |
||||
|
ftp_passwd = input("请输入ftp登录密码:") |
||||
|
while not ftp_passwd: |
||||
|
ftp_passwd = input("ftp登录密码不能为空(重新输入):") |
||||
|
|
||||
|
host = input("请输入ftp的连接ip地址:") |
||||
|
if not host: |
||||
|
host = input("ftp的连接ip地址不能为空(重新输入):") |
||||
|
port = input("请输入ftp连接的端口号地址(默认21):") |
||||
|
if not port: |
||||
|
port = "21" |
||||
|
|
||||
|
print("开始配置git信息") |
||||
|
git_user = input("请输入git的对应地址仓库需要的用户名:") |
||||
|
while not git_user: |
||||
|
git_user = input("git的对应地址仓库需要的用户名不能为空(重新输入):") |
||||
|
|
||||
|
git_passwd = input("请输入git的对应地址仓库需要的密码:") |
||||
|
if not git_passwd: |
||||
|
git_passwd = input("git的对应地址仓库需要的密码不能为空(重新输入):") |
||||
|
|
||||
|
url = input("请输入git的对应地址:") |
||||
|
if not url: |
||||
|
url = input("git的对应地址不能为空(重新输入):") |
||||
|
|
||||
|
cf = configparser.ConfigParser() |
||||
|
cf.add_section("ftp") |
||||
|
cf.add_section("git") |
||||
|
cf.set("ftp", "host", host) |
||||
|
cf.set("ftp", "passwd", ftp_passwd) |
||||
|
cf.set("ftp", "user", ftp_user) |
||||
|
cf.set("ftp", "port", port) |
||||
|
cf.set("git", "user", git_user) |
||||
|
cf.set("git", "passwd", git_passwd) |
||||
|
cf.set("git", "url", url) |
||||
|
|
||||
|
with open(file="./.ftp_git.ini", mode="w") as f: |
||||
|
cf.write(f) |
||||
|
return host, port, ftp_user, ftp_passwd, url, git_user, git_passwd |
||||
|
|
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
""" |
||||
|
加载配置 |
||||
|
""" |
||||
|
host, port, ftp_user, ftp_passwd, url, git_user, git_passwd = init_config() |
||||
|
|
||||
|
git_util = GitUtil(user=git_user, git_url=url, passwd=git_passwd, port=port) |
||||
|
ftp_util = FtpUtil(host, ftp_user, ftp_passwd) |
||||
|
code = ftp_util.read_version_file() |
||||
|
file_dir_local = os.getenv('TEMP') + "/" + git_util.dir_name |
||||
|
if code == 1: |
||||
|
with open(".version", "r") as r: |
||||
|
line = r.read() |
||||
|
# 获取到不同的文件路径 |
||||
|
file_paths = git_util.get_diff_file(line) |
||||
|
if file_paths is None: |
||||
|
print("本地文件和线上对比:文件无变化!") |
||||
|
else: |
||||
|
for file in file_paths: |
||||
|
ftp_util.upload_file(file_dir_local + "/" + file, file) |
||||
|
else: |
||||
|
# 如果不存在版本记录文件。那就全部覆盖 |
||||
|
for root, dirs, files in os.walk(file_dir_local): |
||||
|
for name in files: |
||||
|
if ".git" not in root: |
||||
|
ftp_util.upload_file("/".join((root, name)), name) |
||||
|
|
||||
|
# 最后都要用最新的版本记录覆盖线上的版本记录文件 |
||||
|
cur_version = git_util.get_current_version() |
||||
|
with open(".version", "w") as w: |
||||
|
w.write(cur_version) |
||||
|
|
||||
|
ftp_util.upload_file(".version", ".version") |
||||
|
print("已经完成覆盖!当前版本为:%s" % cur_version) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue