独书先生 Menu

python目录和文件名转换成小写或大写

需求

linux服务器有大小写的区分,如果有静态文件的路径为驼峰命名MainStatic/FeatureJs.js,那么只能通过 MainStatic/FeatureJs.js访问,而无法通过mainstatic/featurejs.js访问,那么如何让这两个地址都可以访问呢?

思路

先使用带lua模块的nginx镜像:nginx-lua来托管我们的静态文件,能够实现大写的请求转发到小写上,然后再使用python脚本把静态文件全部改成小写的形式.

操作步骤

1.环境准备

docker, git, node, python3安装

centos下安装 docker, git, node, python环境

2. nginx-lua安装

docker run --name master_nginx_2 \
-v /etc/localtime:/etc/localtime \
-v /software/nginx/cert:/etc/nginx/cert \
-v /software/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /software/nginx/conf.d:/etc/nginx/conf.d \
-v /software/nginx/html:/usr/share/nginx/html \
-v /software/nginx/logs:/var/log/nginx \
--restart=always \
-p 80:80 -p 443:443 \
-d firesh/nginx-lua

3. nginx.conf配置

user nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 2;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 1k;
    gzip_types text/plain text/css application/octet-stream application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png application/x-httpd-php application/vnd.ms-fontobject application/x-font-ttf font/ttf font/opentype font/x-woff image/svg+xml image/x-icon;
    include /etc/nginx/conf.d/*.conf;
}

FAQ

4. nginx配置转发

conf.d目录下,自己的配置文件增加lua转发规则
比如我的conf.d/01_www.lwebapp.com.conf

server {
    listen 80;
    server_name www.lwebapp.com lwebapp.com;   #域名
    rewrite ^(.*)$  https://$host$1 permanent;  #将所有http请求通过rewrite重定向到https
}
server {
    listen 443 ssl;   #SSL协议访问端口号为443。此处如未添加ssl,可能会造成Nginx无法启动
    server_name www.lwebapp.com lwebapp.com;  # 要解析进来的域名

    ssl_certificate       /etc/nginx/cert/3114423_lwebapp.com.pem;
    ssl_certificate_key   /etc/nginx/cert/3114423_lwebapp.com.key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;  #使用此加密套件
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;   #使用该协议进行配置
    ssl_prefer_server_ciphers on; 

    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 2;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 1k;
    gzip_types text/plain text/css application/octet-stream application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/jpeg image/gif image/png application/x-httpd-php application/vnd.ms-fontobject application/x-font-ttf font/ttf font/opentype font/x-woff image/svg+xml image/x-icon;

    location / {
        root   /usr/share/nginx/html/vue-demo;
        index  index.html index.htm;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root /usr/share/nginx/html;
    }
}

5. python脚本

python目录和文件名转换成小写或大写conver.py,放置在nginx/html下,后续html下会放置各个项目的静态文件,所以使用conver.py统一使用脚本处理

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

import os, sys


def convert(rootdir, optype='l'):
    """
    目录/文件名转换成小写或大写
    :param rootdir: 要转换的根目录路径
    :param optype: 操作类型(小写/大写)  小写:optype = 'l'  大写:optype = 'u',默认转换成小写
    :return:
    """
    dirlist = os.listdir(rootdir)
    for index, onedir in enumerate(dirlist):
        if optype == 'l':
            cdir = onedir.lower()
        elif optype == 'u':
            cdir = onedir.upper()
        subdir = os.path.join(rootdir, onedir)

        if onedir != cdir:      # 子目录或文件名不全为小写或大写
            subcdir = os.path.join(rootdir, cdir)
            os.rename(subdir, subcdir)          # 把大写的目录或文件名命名成小写或大写
            dirlist[index] = cdir
            subdir = subcdir

        # print(subdir)
        if os.path.isdir(subdir):
            convert(subdir, optype)

def help():
    print("use: python convert.py 'rootDirPath' {optype:'l'/'u'}")

def main():
    if len(sys.argv) == 2:
        convert(sys.argv[1])
    elif len(sys.argv) == 3:
        convert(sys.argv[1], sys.argv[2])
    else:
        help()
        exit(400)


if __name__ == '__main__':
    main()

6. 项目初始化

前置条件,安装node

# 进入/software/vue-demo/repository 目录
cd /
mkdir -p /software/vue-demo/repository
cd /software/vue-demo/repository

# 拉取初始代码
git clone https://github.com/Dushusir/vue-demo.git

# 进入vue-demo目并安装项目依赖
cd vue-demo
npm install
# 打包
npm run build

# 新建vue-demo
cd ../../../nginx/html
mkdir vue-demo

# 复制到托管目录
cd ../../vue-demo
yes | cp -r repository/vue-demo/dist/* ../nginx/html/vue-demo

7. 一键更新脚本

后续github上传代码后,在服务器任意位置使用 cd / && cd software/vue-demo && sh deploy_vue_demo.sh一键更新发布

#!/bin/bash
# 一键更新部署脚本,目录在:/software/vue-demo/下
# pull下来的网站代码仓库目录
input="repository/vue-demo"
# 挂载到容器的代码目录
output="../nginx/html/vue-demo"
cd $input

# 忽略本地,强制从线上更新下来
git fetch --all
git reset --hard origin/master 
git pull

# 打包
npm run build

# 备份
cd ../../$output && yes | cp -r * ../../../back/vue-demo
# 清空发布目录
rm -rf *
# 复制到发布目录
cd / && cd software/vue-demo && yes | cp -r $input/dist/* $output

# 文件名大写转小写
cd / && cd software/nginx/html && python3 conver.py "endoc" "l"

8. 一键回退脚本

cd / && cd software/vue-demo && sh back_deploy_vue_demo.sh

#!/bin/bash
# 一键回退脚本,目录在:/software/vue-demo/下
# 挂载html代码目录
output="../nginx/html/vue-demo"
# 清空发布目录
cd $output && rm -rf *
# 复制备份到发布目录
cd / && cd software/back/vue-demo && yes | cp -r * ../$output

参考