rst HumanOps Mantra

HumanOps Mantra

HumanOps-mantra.rst
1. **Humans build and fix systems.**
2. **Humans get tired and stressed, they feel happy and sad.**
3. **Systems don't have feelings yet. They only have SLAs.**
4. **Humans need to switch off and on again.**
5. **The wellbeing of human operators impacts the reliability of systems.**
6. **Alert Fatigue == Human Fatigue**
7. **Automate as much as possible, escalate to a human as a last resort.**
8. **Document everything. Train everyone. Save time.**
9. **Kill the shame game.**
10. **Human issues are system issues.**
11. **Human health impacts business health.**
12. **Humans > systems**

rst 在生产中设置django网站的教程。

在生产中设置django网站的教程。

gistfile1.rst
**********************************************************************
Set up Django, Nginx and Gunicorn in a Virtualenv controled by Supervisor
**********************************************************************

Steps with explanations to set up a server using:

* Virtualenv
* Virtualenvwrapper
* Django
* Gunicorn
* Nginx
* Supervisor

Concept
=======

Nginx will face the outside world. It will serve media files (images, CSS, etc) directly from the file system. However, it can't talk directly to Django applications; it needs something that will run the application, feed it requests from the web, and return responses.

That's Gunicorn's job. Gunicorn will create a Unix socket, and serve responses to nginx via the wsgi protocol - the socket passes data in both directions::

    The outside world <-> Nginx <-> The socket <-> Gunicorn

All this family will live into a Virtualenv. Already wondered why Virtualenv is so useful when you develop Pythons's applications? 
Continue to read and you will understand.

Before you start
================

1. Virtualenv
----------

If you don't already use a Virtualenv, you really should consider using it. In a nutshell, the fact is that your operating system have a lot of core modules which depends of Python. That rule is especially right if you use Ubuntu.
So, do you really need to broke up something existant to create somethin new? Well, some guys could answer you "Yes". I'll teach you how to say "No" to them !
Virtualenv will create a dedicated virtual environment with his python binary as well as his own modules. With that method, your Virtualenv will be isolated from the rest of the system. 

1.5 Pip (optional, but higly recommanded)
-------------------------------------

If you use Pip, and I clearly recommand to use it, Virtualenv will simplify your life, because if you play well, you only have to do ::

    pip freeze > requirements.txt

to print a list of all the modules needed by your project into a file. When you will deploy it, you will be able to install all those module with a ::

    pip install -r requirements.txt

2. Virtualenvwrapper
-----------------

What ? I didn't explained how to use Virtualenv? Well, indeed I lied. We won't be using Virtualenv directly. We will use a wrapper. Virtualenvwrapper to be right. Original, isn't it?
Virtualenvwrapper will allow you to easily create virtualenv and switching between them.

Let's get started ! To install virtualenvwrapper, install it with Pip, apt-get, whatever::

    pip install virtualenvwrapper

Virtualenvwrapper is now installed? Let's play with him. First, you will need to modify your .bashrc with your favourite text editor. Add this lines at the and of your .bashrc ::

    export WORKON_HOME=~/.virtualenvs
    export PROJECT_HOME=/path/to/your/project/home
    source /usr/local/bin/virtualenvwrapper.sh

WORKON_HOME is required but PROJECT_HOME is needless. Don't forget to always put ALL the export's directives before sourcing your file.
Seems legit for you?  Here, have my like !

Now, let's activate our .bashrc. If you are a UNIX guru, you have problably already did it before I explained it. If not, here is the command ::

    source .bashrc

If all is good, your stdout will be sourced byt the output of the Virtualenvwrapper creating script. You can verify it by searching a .virtualenvs folder is your home directory.

Now, let's ceate our virtualenv for our project. You can name it whatever your want and even if you don't remember, just go into your .virtualenvs folder and the name of your virtualenv will be one of the folder.
The command for creating one is ::

    mkvirtualenv nameofyourproject

The command for working on a specified virtualenv is ::

    workon nameofyourproject

The command for deactivate a specified virtualenv is ::

    deactivate nameofyourproject

And finally the command to remove a specified virtualenv is ::

    rmvirtualenv nameofyourproject

That's all the command you need to remember. If the workon command has successfully created a virtualenv, your should see the name of your project between parentheses in the left of your username@nameofyourcomputer. Something like that ::

    (nameofyourproject)username@nameofyourcomputer

All is good, Okey, let's move to the next of the story.

! REMEMBER TO DO ALL THE NEXT PART IN YOUR VIRTUALENV. ONLY SUPERVISOR WILL BE INSTALLED OUTSIDE YOUR VIRTUALENV !

1. Django
------

I'm assuming you are using Django 1.4.x. Everything should be fine from our right for Django 1.5. Anayway, if you created your project in 1.4, it should have automatically created a wsgi module. If you're using an earlier version, you will have to find a Django wsgi module for your project. Here is mine modified for exemple ::

    import os
    import sys


    root = os.path.join(os.path.dirname(__file__), '..')
    sys.path.insert(0, root)


    os.environ['DJANGO_SETTINGS_MODULE'] = 'nameofyourproject.settings'


    import django.core.handlers.wsgi
    application = django.core.handlers.wsgi.WSGIHandler()

    # This application object is used by any WSGI server configured to use this
    # file. This includes Django's development server, if the WSGI_APPLICATION
    # setting points here.
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()

   # Apply WSGI middleware here.
   # from helloworld.wsgi import HelloWorldApplication
   # application = HelloWorldApplication(application)

Note that I'm also assuming a Django 1.4 project structure, in which you see paths like::

	/path/to/your/project/project/

(i.e. it creates nested directories with the name of your project). Adjust the examples if you using an earlier Django.

It will also be helpful if you are in your Django project's directory. If you don't have one ready, just create a directory for now.

About the domain and port
-------------------------

I'll call your domain domain.tld. Substitute your own FQDN or IP address.

Throughout, I'm using the port (:8000) for tests because it is the same port as Django's dev web server. The default port for http (:80) will be used for real deployment. You can use whatever port you want of course, but if you don't know what NAT is, don't do it.

Basic Gunicorn installation and configuration
=========================================

Install Gunicorn
-------------
As we said earlier, Gunicorn will serve the core of our application, just like the Django's development web server would do it. Let's install it ::

    pip install gunicorn

Basic test
----------

Create a file called myapp.py::

    def app(environ, start_response):
        data = "Hello, World!\n"
        start_response("200 OK", [
            ("Content-Type", "text/plain"),
            ("Content-Length", str(len(data)))
        ])
    return iter([data])

Run::

	gunicorn -w 4 myapp:app

This should serve a hello world message directly to the browser on port 8000. Visit::

	http://127.0.0.1:8000

to check.                       

Test your Django project
------------------------

Now we want gunicorn to do the same thing, but to run a Django site instead of the test.py module.

But first, make sure that your project actually works! Now you need to be in your Django project directory.

::

	python manage.py runserver 0.0.0.0:8000

Now run it using gunicorn::

	gunicorn nameofyourapp.wsgi:app

Point your browser at the server; if the site appears, it means gunicorn can serve your Django application from your virtualenv. Media/static files may not be served properly, but don't worry about that.

Now normally we won't have the browser speaking directly to gunicorn: nginx will be the go-between.

Basic nginx
===========

Install nginx
-------------

The version of Nginx from Debian stable and Ubuntu is rather old. We'll install from backports for Debian and PPA for Ubuntu.

Debian::

	sudo nano /etc/apt/sources.list     # edit the sources list

Add::

	# backports
	deb http://backports.debian.org/debian-backports squeeze-backports main

Run::

	sudo apt-get -t squeeze-backports install nginx	# install nginx

For Ubuntu::

	sudo -s
	nginx=stable # use nginx=development for latest development version
	add-apt-repository ppa:nginx/$nginx
	apt-get update 
	apt-get install nginx

For both::

	sudo /etc/init.d/nginx start	# start nginx

And now check that the server is serving by visiting it in a web browser on port 80 - you should get a message from nginx: "Welcome to nginx!"

Configure nginx for your site
-----------------------------

Create a file called nginx.conf, and put this in it::

    server {
        # the port your site will be served on
        listen      80;
        # the domain name it will serve for
        server_name .domain.tld ip.adress;   # substitute by your FQDN and machine's IP address
        charset     utf-8;

        #Max upload size
        client_max_body_size 75M;   # adjust to taste

        # Django media
        location /media  {
    	    alias /var/www/path/to/your/project/media;      # your Django project's media files
        }

        location /assets {
    	    alias /var/www/path/to/your/project/static;     # your Django project's static files
        }

        # Finally, send all non-media requests to the Django server.
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }

Move your file to /etc/nginx/sites-enabled so nginx can see it::

	sudo mv /path/to/your/project/nginx.conf /etc/nginx/sites-enabled/

Basic nginx test
----------------

Restart nginx::

	sudo /etc/init.d/nginx restart

Check that media files are being served correctly:

Add an image called media.png to the /path/to/your/project/project/media directory

Visit 

http://domain.tld:80/media/media.png     

If this works, you'll know at least that nginx is serving files correctly.

Running the Django application with uswgi and nginx
===================================================

Let's run our Django application::

	gunicorn nameofyourapp.wsgi:app

Now gunicorn and nginx should be serving up your Django application.

Make gunicorn startup when the system boots
========================================

The last step is to make it all happen automatically at system startup time.

To do this, we will install a programm called supervisor::

    sudo pip install supervisor

Sudo in front of your command is important, because it means that our supervisor programm will be installed in the system and not in a virtualenv.

Now, we will create a bash file to execute some commands such as activate our virtualenv and browsing to our directory. So create a nameoryourproject.sh file::

    #!/bin/bash
    WORKING_DIR=/path/to/your/project
    ACTIVATE_PATH=/path/to/your/virtualenv/bin/activate
    cd ${WORKING_DIR}
    source ${ACTIVATE_PATH}
    exec $@

Next, we create a file named supervisord.conf and we put it in /etc/ ::

    ; Sample supervisor config file.
    ;
    ; For more information on the config file, please see:
    ; http://supervisord.org/configuration.html
    ;
    ; Note: shell expansion ("~" or "$HOME") is not supported.  Environment
    ; variables can be expanded using this syntax: "%(ENV_HOME)s".
    
    [unix_http_server]
    file=/tmp/supervisor.sock   ; (the path to the socket file)
    chmod=0700                 ; socket file mode (default 0700)
    chown=root:root       ; socket file uid:gid owner
    ;username=noname              ; (default is no username (open server))
    ;password=noname               ; (default is no password (open server))

    ;[inet_http_server]         ; inet (TCP) server disabled by default
    ;port=127.0.0.1:9001        ; (ip_address:port specifier, *:port for all iface)
    ;username=noname              ; (default is no username (open server))
    ;password=noname               ; (default is no password (open server))

    [supervisord]
    logfile=/var/log/supervisord/supervisord.log ; (main log file;default $CWD/supervisord.log)
    logfile_maxbytes=50MB        ; (max main logfile bytes b4 rotation;default 50MB)
    logfile_backups=10           ; (num of main logfile rotation backups;default 10)
    loglevel=info                ; (log level;default info; others: debug,warn,trace)
    pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
    nodaemon=true               ; (start in foreground if true;default false)
    minfds=1024                  ; (min. avail startup file descriptors;default 1024)
    minprocs=200                 ; (min. avail process descriptors;default 200)
    ;umask=022                   ; (process file creation umask;default 022)
    user=root                 ; (default is current user, required if root)
    ;identifier=supervisor       ; (supervisord identifier, default is 'supervisor')
    ;directory=/tmp              ; (default is not to cd during start)
    ;nocleanup=true              ; (don't clean up tempfiles at start;default false)
    ;childlogdir=/tmp            ; ('AUTO' child log dir, default $TEMP)
    ;environment=KEY=value       ; (key value pairs to add to environment)
    ;strip_ansi=false            ; (strip ansi escape codes in logs; def. false)
    
    ; the below section must remain in the config file for RPC
    ; (supervisorctl/web interface) to work, additional interfaces may be
    ; added by defining them in separate rpcinterface: sections
    [rpcinterface:supervisor]
    supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
    
    [supervisorctl]
    serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL  for a unix socket
    ;serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
    ;username=www-data              ; should be same as http_username if set
    ;password=www-data                ; should be same as http_password if set
    ;prompt=mysupervisor         ; cmd line prompt (default "supervisor")
    ;history_file=~/.sc_history  ; use readline history if available
    
    ; The below sample program section shows all possible program subsection values,
    ; create one or more 'real' program: sections to be able to control them under
    ; supervisor.
    
    ;[program:theprogramname]
    ;command=/bin/cat              ; the program (relative uses PATH, can take args)
    ;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
    ;numprocs=1                    ; number of processes copies to start (def 1)
    ;directory=/tmp                ; directory to cwd to before exec (def no cwd)
    ;umask=022                     ; umask for process (default None)
    ;priority=999                  ; the relative start priority (default 999)
    ;autostart=true                ; start at supervisord start (default: true)
    ;autorestart=unexpected        ; whether/when to restart (default: unexpected)
    ;startsecs=1                   ; number of secs prog must stay running (def. 1)
    ;startretries=3                ; max # of serial start failures (default 3)
    ;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
    ;stopsignal=QUIT               ; signal used to kill process (default TERM)
    ;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
    ;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
    ;killasgroup=false             ; SIGKILL the UNIX process group (def false)
    ;user=chrism                   ; setuid to this UNIX account to run the program
    ;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
    ;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
    ;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
    ;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    ;stdout_events_enabled=false   ; emit events on stdout writes (default false)
    ;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
    ;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
    ;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
    ;stderr_events_enabled=false   ; emit events on stderr writes (default false)
    ;environment=A=1,B=2           ; process environment additions (def no adds)
    ;serverurl=AUTO                ; override serverurl computation (childutils)
    
    ; The below sample eventlistener section shows all possible
    ; eventlistener subsection values, create one or more 'real'
    ; eventlistener: sections to be able to handle event notifications
    ; sent by supervisor.
    
    ;[eventlistener:theeventlistenername]
    ;command=/bin/eventlistener    ; the program (relative uses PATH, can take args)
    ;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
    ;numprocs=1                    ; number of processes copies to start (def 1)
    ;events=EVENT                  ; event notif. types to subscribe to (req'd)
    ;buffer_size=10                ; event buffer queue size (default 10)
    ;directory=/tmp                ; directory to cwd to before exec (def no cwd)
    ;umask=022                     ; umask for process (default None)
    ;priority=-1                   ; the relative start priority (default -1)
    ;autostart=true                ; start at supervisord start (default: true)
    ;autorestart=unexpected        ; whether/when to restart (default: unexpected)
    ;startsecs=1                   ; number of secs prog must stay running (def. 1)
    ;startretries=3                ; max # of serial start failures (default 3)
    ;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
    ;stopsignal=QUIT               ; signal used to kill process (default TERM)
    ;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
    ;stopasgroup=false             ; send stop signal to the UNIX process group (default false)
    ;killasgroup=false             ; SIGKILL the UNIX process group (def false)
    ;user=chrism                   ; setuid to this UNIX account to run the program
    ;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
    ;stdout_logfile=/a/path        ; stdout log path, NONE for none; default AUTO
    ;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
    ;stdout_events_enabled=false   ; emit events on stdout writes (default false)
    ;stderr_logfile=/a/path        ; stderr log path, NONE for none; default AUTO
    ;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
    ;stderr_logfile_backups        ; # of stderr logfile backups (default 10)
    ;stderr_events_enabled=false   ; emit events on stderr writes (default false)
    ;environment=A=1,B=2           ; process environment additions
    ;serverurl=AUTO                ; override serverurl computation (childutils)
    
    ; The below sample group section shows all possible group values,
    ; create one or more 'real' group: sections to create "heterogeneous"
    ; process groups.
    
    ;[group:thegroupname]
    ;programs=progname1,progname2  ; each refers to 'x' in [program:x] definitions
    ;priority=999                  ; the relative start priority (default 999)
    
    ; The [include] section can just contain the "files" setting.  This
    ; setting can list multiple files (separated by whitespace or
    ; newlines).  It can also contain wildcards.  The filenames are
    ; interpreted as relative to this file.  Included files *cannot*
    ; include files themselves.
    
    ;[include]
    ;files = relative/directory/*.ini
    [program:nameofyourprogram]
    directory = /path/of/your/project/
    user = www-data
    command = /path/to/your/nameofyourproject.sh gunicorn nameofyourproject.wsgi:application
    stdout_logfile = /var/log/supervisord/access.log
    stderr_logfile = /var/log/supervisord/error.log

After, we will create a file which will ask supervisord to boot at the startup.

Create a file named supervisord::

    # Supervisord auto-start
    #
    # description: Auto-starts supervisord
    # processname: supervisord
    # pidfile: /var/run/supervisord.pid
 
    SUPERVISORD=/usr/local/bin/supervisord
    SUPERVISORD_ARGS='-c /etc/supervisord.conf'
    SUPERVISORCTL=/usr/local/bin/supervisorctl

    case $1 in
    start)
        echo -n "Starting supervisord: "
        $SUPERVISORD $SUPERVISORD_ARGS
        echo
        ;;
    stop)
        echo -n "Stopping supervisord: "
        $SUPERVISORCTL shutdown
        echo
        ;;
    restart)
        echo -n "Stopping supervisord: "
        $SUPERVISORCTL shutdown
        echo
        echo -n "Starting supervisord: "
        $SUPERVISORD $SUPERVISORD_ARGS
        echo
        ;;
    esac

Make it executable ::

    chmod +x supervisord

Move it to /etc/init.d ::

    mv supervisord /etc/init.d/

Make it boot at the start ::

    sudo update-rc.d supervisord defaults

Reboot your system and your website should live through the ages.

rst 如何使用LXC> = 1.0创建容器

如何使用LXC> = 1.0创建容器

creatingContainers.rst
How to setup a host to use LXC
------------------------------

Create the bridge where all LXC devices will be attached 

.. code-block:: bash 

    auto eth2
    iface eth2 inet manual

    auto br-eth2
    iface br-eth2 inet static
            address 10.51.50.1
            netmask 255.255.255.0
            bridge_ports eth2
            bridge_stp off
            bridge_fd 0
            bridge_maxwait 0
            dns-nameservers 69.20.0.164 69.20.0.196


If not deploying on Ubuntu 14.04 add this PPA to the system to provide for LXC 1.x

.. code-block:: bash 

    # Add the LXC Stable back ports repo
    add-apt-repository -y ppa:ubuntu-lxc/stable

    # Update
    apt-get update


Install the LXC packages

.. code-block:: bash 

    # Install LXC
    apt-get -y install lxc python3-lxc lxc-templates liblxc1


Create a default LXC configuration file to build with

.. code-block:: bash

    # Update the lxc-rpc.conf file
    cat > /etc/lxc/lxc-rpc.conf <<EOF
    lxc.start.auto = 1
    lxc.group = rpc

    # Default LXC network
    lxc.network.type = veth
    lxc.network.name = eth0
    lxc.network.link = lxcbr0
    lxc.network.flags = up
    lxc.network.hwaddr = 00:16:3e:xx:xx:xx

    # Create a veth pair within the container
    lxc.network.type = veth
    # Network device within the container
    lxc.network.name = eth1
    # Host link to attach to, this should be a bridge
    lxc.network.link = br-eth2
    # Hardware Address
    lxc.network.hwaddr = 00:16:3e:xx:xx:xx
    # enable the device on boot
    lxc.network.flags = up
    EOF


Setup LVM if possible
---------------------

.. code-block:: bash

    if [ -e "/dev/xvde" ];then
      apt-get update && apt-get install lvm2
      parted -s /dev/xvde mktable gpt
      parted -s /dev/xvde mkpart lvm 0GB 100%
      pvcreate /dev/xvde1
      vgcreate lxc /dev/xvde1
    fi


How to create a container
-------------------------

Build the first container

.. code-block:: bash

    # Note: $CONTAINER_NAME is a string
    # Note: $CONTAINER_PACKAGES is a comma separated list
    lxc-create -n $CONTAINER_NAME \
               -t ubuntu \
               -f /etc/lxc/lxc-rpc.conf \
               -- \
               --release $DISTRO_NAME \
               --user openstack \
               --password secrete \
               --packages $CONTAINER_PACKAGES


Before you start the container assign it an IP address. Change the eth1 address
for your environment.

.. code-block:: bash

    cat > /var/lib/lxc/$CONTAINER_NAME/rootfs/etc/network/interfaces <<EOF
    # The loopback network interface
    auto lo
    iface lo inet loopback

    # Label public
    auto eth0
    iface eth0 inet dhcp

    # Bridged Network
    auto eth1
    iface eth1 inet static
        address 10.51.50.$ADDRESS
        netmask 255.255.255.0
        gateway 10.51.50.1
    EOF


Now start the container

.. code-block:: bash 

    lxc-start -d --name $CONTAINER_NAME


Make sure SSH starts up by default

.. code-block:: bash 

    lxc-attach --name $CONTAINER_NAME <<EOL
        update-rc.d ssh defaults
        service ssh restart
    EOL


Now your ready to get building.

rst PyCharm快捷方式和键盘映射

PyCharm快捷方式和键盘映射

PyCharm-Shortcuts-and-Keymap.rst
.. contents::

PyCharm Shortcut Key
==============================================================================
在默认设置的基础上加一些个人的自定义。

- Windosw下使用Default。
- MacOS下使用MacOS.


General
------------------------------------------------------------------------------

.. list-table:: General
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Copy / Cut / Paste (复制 / 剪切 / 粘贴)
      - Ctrl + C / Ctrl + X / Ctrl + V
      - Cmd + C / Cmd + X / Cmd + V
      -

    * - Undo / Redo (撤销 / 重做)
      - Ctrl + Z / Ctrl + Y
      - Cmd + Z / Cmd + Y
      -

    * - Open (打开文件/文件夹)
      - Ctrl + O
      - Cmd + O

    * - Save (保存改动)
      - Ctrl + S
      - Cmd + S
      -

    * - Rename File (重命名文件名)
      - Shift + F6
      - Shift + F6
      -

    * - Quit (退出程序)
      - Alt + F4
      - Cmd + Q
      -

    * - Close Tab (关闭标签页)
      - Ctrl + W
      - Cmd + W
      -


Edit
------------------------------------------------------------------------------

.. list-table:: Edit
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Title Case (标题化字符串, 每个单词第一个字母大写, 其他小写)
      -
      -
      -

    * - Swap Case (交换大小写)
      -
      -
      -

    * - Upper Case (全部大写)
      -
      -
      -

    * - Lower Case (全部小写)
      -
      -
      -


Select
------------------------------------------------------------------------------

.. list-table:: Select
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Select All (选择全部)
      - Ctrl + A
      - Cmd + A
      -

    * - Expand Selection Line (选择光标所在行)
      -
      -
      -

    * - Expand Selection to Word (选择光标所在的单词)
      -
      -
      -

    * - Expand Selection to Paragraph (选择光标所在的段落)
      -
      -
      -

    * - Add Previous Line (添加光标所在的 **上一行** 到 "已选择")
      -
      -
      -

    * - Add Next Line (添加光标所在的 **下一行** 到 "已选择")
      -
      -
      -

    * - Select Between Bracket (选择括号之间的内容)
      -
      -
      -


Find
------------------------------------------------------------------------------

.. list-table:: Editing
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Find (搜索文本)
      - Ctrl + F
      - Ctrl + F
      -

    * - Find in Directory (在目录中的所有文件中搜索文本)
      - Shift + Ctrl + F
      - Shift + Ctrl + F
      -

    * - Replace (替换)
      - Ctrl + R
      - Ctrl + R
      -

    * - Replace in Directory (在目录中的所有文件中替换文本)
      - Shift + Ctrl + R
      - Shift + Ctrl + R
      -

    * - Find and Select Next (找到并选择 **下一个** 匹配)
      - Ctrl + G
      - Cmd + G
      -

    * - Find and Select Previous (找到并选择 **上一个** 匹配)
      - Shift + Ctrl + G
      - Shift + Cmd + G
      -

    * - Find and Select All (找到并选择全部)
      -
      -
      -

    * - Find and Add Select Next (找到并将 **下一个** 匹配添加到已选项)
      -
      -
      -

    * - Find and Multiple Edit (搜索到 **所有** 匹配后同时编辑)
      - Ctrl + F -> Alt + Enter
      - Ctrl + F -> Alt + Enter
      -


Line
------------------------------------------------------------------------------

.. list-table:: General
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Insert Line After (在 **下面** 另起一行, 光标跳到 **下一行**)
      - Shift + Enter
      - Shift + Enter
      -

    * - Insert Line Before (在 **上面** 另起一行, 光标跳到 **上一行**)
      - Ctrl + Alt + Enter
      - Cmd + Alt + Enter
      -

    * - Duplicate / Delete Line (复制/删除 该行)
      - Ctrl + D / Ctrl + Alt + D
      - Cmd + D / Cmd + BackSpace
      -

    * - Indent / Unindent Line (增加/减少 该行缩进)
      - Tab / Shift + Tab
      - Tab / Shift + Tab
      -

    * - Move Line Up/Down (移动该行)
      - Shift + Alt + Up/Down
      - Shift + Alt + Up/Down
      -

    * - Join Lines (连接多行)
      - Ctrl + Shift + J
      - Ctrl + Shift + J
      -

    * - Multiline Editing (多行同时编辑)
      - Alt + Click/Drag or Press Ctrl Twice + Up/Down to select lines
      - Cmd + Click/Drag or Press Alt Twice + Up/Down to select lines
      - Alt + Click/Drag or Press Ctrl Twice + Up/Down to select lines

    * - Sort Lines (多行排序)
      -
      -
      -


Navigation
------------------------------------------------------------------------------

.. list-table:: Navigation
    :widths: 10 10 10 10
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Previous/Next Tab (上/下 一个标签)
      - Alt + Left/Right
      - Shift + Cmd + ``[`` / ``]``
      -

    * - Previous/Next Cursor (上/下 一个游标所在)
      - Ctrl + Alt + Left/Right
      - Cmd + Alt + Left/Right
      -

    * - Jump Between Bracket (在匹配的括号之间跳转)
      - Ctrl + Shift + M
      - Ctrl + M
      -


Menu
------------------------------------------------------------------------------

.. list-table:: Menu
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Settings (设定)
      - Ctrl + Alt + S
      - Cmd + ,
      -

    * - Pluggin (插件)
      -
      -
      -


IDLE
------------------------------------------------------------------------------

.. list-table:: IDLE
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Copy Name (复制文件/文件夹名)
      -
      -
      -

    * - Copy Absolute Path (复制绝对路径)
      - Shift + Ctrl + C
      - Shift + Cmd + C
      -

    * - Open in Explorer/Finder/File Manager (在文件浏览器中打开)
      - Ctrl + Shift + I
      - Ctrl + Shift + I
      -

    * - Open in Sublime Text (使用Sublime Text打开)
      - Ctrl + Shift + S
      - Ctrl + Shift + S
      -

    * - Open in Default Application (使用默认的App打开)
      -
      -
      -

    * - Run Last File (运行上次运行的脚本)
      - Shift + F10
      - Ctrl + R
      -

    * - Select and Run (选择一个脚本运行)
      - Alt + Shift + F10 (2 is the current file)
      - Alt + Ctrl + R (2 is the current file)
      -

    * - Debug Last File (调试上次运行的脚本)
      - Shift + F9
      - Ctrl + D
      -

    * - Select and Debug (选择一个脚本调试)
      - Alt + Shift + F9 (2 is the current file)
      - Alt + Ctrl + D (2 is the current file)
      -

    * - Open Command Line/Terminal (打开命令行)
      - Alt + F12
      - Alt + F12
      -

    * - Fold/Unfold All Once (折叠/打开 代码一次)
      - Ctrl + ``+``/``-``
      - Ctrl + ``+``/``-``
      -

    * - Fold/Unfold All Recursively (折叠/打开 全部代码)
      - Ctrl + Shift + ``+``/``-``
      - Ctrl + Shift + ``+``/``-``
      -

    * - Bookmark Here (为某处添加书签)
      - F11
      - F3
      -

    * - Show ALl Bookmark (浏览所有的书签)
      - Shift + F11
      - Cmd + F3
      -


Python
------------------------------------------------------------------------------

.. list-table:: Python
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Comment/Uncomment (注释/取消注释)
      - Ctrl + ``/``
      - Ctrl + ``/``
      -

    * - Navigate to Previous/Next Method (上/下一个函数)
      - Alt + Up/Down
      - Ctrl + Up/Down (Has to disable MacOS's shortcut ``Mission Control`` and ``Application Window``)
      -

    * - Move Method/Class Up/Down (移动整个函数和类的位置)
      - Ctrl + Shift +
      - Shift + Cmd + Up/Down
      -

    * - Find Usage (在项目中查找用例)
      - Alt + F7
      - Alt + F7
      -

    * - Find Usage in File (在本文件中查找用例)
      - Ctrl + F7
      - Cmd + F7
      -

    * - Highlight Usage in File (高亮本文件中的所有用例)
      - Shift + Ctrl + F7
      - Shift + Cmd + F7
      -

    * - Go to Declaration (到第一次的声明处)
      - Ctrl + B
      - Cmd + B
      -

    * - Go to Implementation (到实现处, 可能有多个)
      - Ctrl + Alt + B
      - Cmd + Alt + B
      -

    * - View Definition (快速查看定义)
      - Ctrl + Shift + I
      - Alt + Space
      -

    * - View Document (快速查看文档)
      - Ctrl + Q
      - F1
      -

    * - Pep8 Reformat (Pep8风格化代码)
      - Ctrl + Alt + L
      - Cmd + Alt + L
      -

    * - Optimize Import (自动整理Import)
      - Ctrl + Alt + O
      - Ctrl + Alt + O
      -

    * - Rename Variable (重命名变量)
      - Shift + F6
      - Shift + F6
      -

rst Sublime快捷方式和键盘映射

Sublime快捷方式和键盘映射

Sublime-Shortcuts-and-Keymap.rst
.. contents::

Sublime Shortcuts and Keymap
==============================================================================


General
------------------------------------------------------------------------------

.. list-table:: General
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Copy / Cut / Paste (复制 / 剪切 / 粘贴)
      - Ctrl + C / Ctrl + X / Ctrl + V
      - Cmd + C / Cmd + X / Cmd + V
      -

    * - Undo / Redo (撤销 / 重做)
      - Ctrl + Z / Ctrl + Y
      - Cmd + Z / Cmd + Y
      -

    * - Open (打开文件/文件夹)
      - Ctrl + O
      - Cmd + O
      -

    * - Save (保存改动)
      - Ctrl + S
      - Cmd + S
      -

    * - Rename File (重命名文件名)
      - Shift + Ctrl + P (Goto Everythign) -> Enter: "Rename"
      - Ctrl + P (Goto Everythign) -> Enter: "Rename"
      -

    * - Quit (退出程序)
      - Alt + F4
      - Cmd + W
      -

    * - Close Tab (关闭标签页)
      - Ctrl + W
      - Cmd + W
      -

    * - Go to everything (超级控制台)
      - Shift + Ctrl + P
      - Shift + Cmd + P
      -

    * - Go to into File (前往某个文件)
      - Ctrl + P
      - Cmd + P
      -

    * - Go to Symbol, Class, Function (前往标记, 类, 方法)
      - Ctrl + R
      - Cmd + R
      -

    * - Jump to line by line number (跳到特定行)
      - Ctrl + G
      - Cmd + G
      -


Edit
------------------------------------------------------------------------------

.. list-table:: Edit
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Title Case (标题化字符串, 每个单词第一个字母大写, 其他小写)
      - Ctrl + Shift + Alt + T
      - Shift + Alt + Cmd + T
      -

    * - Swap Case (交换大小写)
      - Ctrl + Shift + Alt + S
      - Shift + Alt + Cmd + S
      -

    * - Upper Case (全部大写)
      - Ctrl + Shift + Alt + U
      - Shift + Alt + Cmd + U
      -

    * - Lower Case (全部小写)
      - Ctrl + Shift + Alt + L
      - Shift + Alt + Cmd + L
      -


Select
------------------------------------------------------------------------------

.. list-table:: Select
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Select All (选择全部)
      - Ctrl + A
      - Cmd + All
      -

    * - Expand Selection Line (选择光标所在行)
      - Ctrl + L
      - Cmd + L
      -

    * - Expand Selection to Word (选择光标所在的单词)
      - Ctrl + D
      - Cmd + D
      -

    * - Expand Selection to Paragraph (选择光标所在的段落)
      -
      -
      -

    * - Add Previous Line (添加光标所在的 **上一行** 到 "已选择")
      - Ctrl + Alt + Up
      - Shift + Alt + Up
      -

    * - Add Next Line (添加光标所在的 **下一行** 到 "已选择")
      - Ctrl + Alt + Up
      - Shift + Alt + Down
      -

    * - Select Between Bracket (选择括号之间的内容)
      - Shift + Ctrl + M
      - Shift + Ctrl + M
      -


Find
------------------------------------------------------------------------------

.. list-table:: Editing
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Find (搜索文本)
      - Ctrl + F
      - Cmd + F
      -

    * - Find in Directory (在目录中的所有文件中搜索文本)
      - Shift + Ctrl + F
      - Shift + Cmd + F
      -

    * - Replace (替换)
      - Ctrl + H
      - Cmd + Alt + F
      -

    * - Replace in Directory (在目录中的所有文件中替换文本)
      -
      -
      -

    * - Find and Select Next (找到并选择 **下一个** 匹配)
      - F3
      - Cmd + G
      -

    * - Find and Select Previous (找到并选择 **上一个** 匹配)
      - Shift + F3
      - Shift + Cmd + G
      -

    * - Find and Select All (找到并选择全部)
      - Alt + F3
      - Ctrl + Cmd + G
      -

    * - Find and Add Select Next (找到并将 **下一个** 匹配添加到已选项)
      - Ctrl + D
      - Cmd + D
      -

    * - Find and Multiple Edit (搜索到 **所有** 匹配后同时编辑)
      - Ctrl + F -> Enter -> Alt + Enter (Select All Found)
      - Cmd + F -> Enter -> Alt + Enter (Select All Found)
      -


Line
------------------------------------------------------------------------------

.. list-table:: General
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Insert Line After (在 **下面** 另起一行, 光标跳到 **下一行**)
      - Ctrl + Enter
      - Cmd + Enter
      -

    * - Insert Line Before (在 **上面** 另起一行, 光标跳到 **上一行**)
      -
      -
      -

    * - Duplicate/Delete Line (复制/删除 该行)
      - Shift + Ctrl + D
      - Shift + Cmd + D
      -

    * - Indent/Unindent Line (增加/减少 该行缩进)
      - Ctrl + ``]`` / ``[``
      - Cmd + ``]`` / ``[``
      -

    * - Move Line Up/Down (移动该行)
      - Shift + Ctrl + Up/Down
      - Ctrl + Cmd + Up/Down
      -

    * - Join Lines (连接多行)
      - Ctrl + J
      - Cmd + J
      -

    * - Multiline Editing (多行同时编辑)
      - Shift + Ctrl + L
      - Shfit + Cmd + L
      -

    * - Sort Lines Case Insensitive/Sensitiev (多行排序)
      - F9 / Ctrl + F9
      - F5 / Ctrl + F5
      -


Navigation
------------------------------------------------------------------------------

.. list-table:: Navigation
    :widths: 10 10 10 10
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Previous/Next Tab (上/下 一个标签)
      - Ctrl + PageUp/PageDown
      - Cmd + Alt + Left/Right
      -

    * - Previous/Next Cursor (上/下 一个游标所在)
      - Alt + ``-`` / Shift + Alt + ``-``
      - Ctrl + ``-`` / Shift + Ctrl + ``-``
      -

    * - Jump Between Bracket (在匹配的括号之间跳转)
      - Ctrl + M
      - Ctrl + M
      -


Menu
------------------------------------------------------------------------------

.. list-table:: Menu
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Settings (设定)
      -
      - Cmd + ``,``
      -

    * - Pluggin (插件)
      -
      - Shift + Cmd + P (Go to anything) -> Enter: "Package xxx"
      -

    * - Python Console (呼出Python控制台)
      - Ctrl + `````
      - Ctrl + `````
      -


IDLE
------------------------------------------------------------------------------

.. list-table:: IDLE
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Copy Name (复制文件/文件夹名)
      - Shift + Ctrl + P (Go to anything) -> Enter: "Copy name"
      - Shift + Cmd + P (Go to anything) -> Enter: "Copy name"
      -

    * - Copy Absolute Path (复制绝对路径)
      - Shift + Ctrl + P (Go to anything) -> Enter: "Copy Path"
      - Shift + Cmd + P (Go to anything) -> Enter: "Copy Path"
      -

    * - Open in Explorer/Finder/File Manager (在文件浏览器中打开)
      -
      -
      -

    * - Open in Default Application (使用默认的App打开)
      -
      -
      -

    * - Run This File (运行当前编辑的脚本)
      - Ctrl + B / Shift + Ctrl + B, 运行当前脚本 / 选择解释器运行当前脚本
      - Cmd + B / Shift + Cmd + B, 运行当前脚本 / 选择解释器运行当前脚本
      -

    * - Run Last File (运行上次运行的脚本)
      -
      -
      -

    * - Select and Run (选择一个脚本运行)
      -
      -
      -

    * - Debug This File (调试当前编辑的脚本)
      -
      -
      -

    * - Debug Last File (调试上次运行的脚本)
      -
      -
      -

    * - Select and Debug (选择一个脚本调试)
      -
      -
      -

    * - Open Command Line/Terminal (打开命令行)
      -
      -
      -

    * - Fold/Unfold All Once (折叠/打开 代码一次)
      - Shift + Ctrl + ``[`` / ``]``
      - Cmd + Alt + ``[`` / ``]``
      -

    * - Fold/Unfold All Recursively (折叠/打开 全部代码)
      -
      -
      -


Python
------------------------------------------------------------------------------

.. list-table:: Python
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Navigate to Previous/Next Method (上/下一个函数)
      -
      -
      -

    * - Move Method/Class Up/Down (移动整个函数和类的位置)
      -
      -
      -

    * - Find Usage (在项目中查找用例)
      -
      -
      -

    * - Find Usage in File (在本文件中查找用例)
      -
      -
      -

    * - Go to Declaration (到第一次的声明处)
      -
      -
      -

    * - Go to Implementation (到实现处, 可能有多个)
      -
      -
      -

    * - View Definition (快速查看定义)
      -
      -
      -

    * - View Document (快速查看文档)
      -
      -
      -

    * - Pep8 Reformat (Pep8风格化代码)
      -
      -
      -

    * - Optimize Import (自动整理Import)
      -
      -
      -

    * - Rename Variable (重命名变量)
      -
      -
      -

    * - Bookmark Here (为某处添加书签, 以便快速浏览)
      -
      -
      -

    * - Show ALl Bookmark (浏览所有的书签)
      -
      -
      -

rst TextEditor / IDLE的键映射文档的模板

TextEditor / IDLE的键映射文档的模板

Keymap-Template.rst
.. contents::

General
------------------------------------------------------------------------------

.. list-table:: General
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Copy / Cut / Paste (复制 / 剪切 / 粘贴)
      - 
      - 
      - 

    * - Undo / Redo (撤销 / 重做)
      - 
      - 
      - 

    * - Open (打开文件/文件夹)
      - 
      - 
      - 

    * - Save (保存改动)
      - 
      - 
      - 

    * - Rename File (重命名文件名)
      - 
      - 
      - 

    * - Quit (退出程序)
      - 
      - 
      - 

    * - Close Tab (关闭标签页)
      - 
      - 
      - 


Edit
------------------------------------------------------------------------------

.. list-table:: Edit
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Title Case (标题化字符串, 每个单词第一个字母大写, 其他小写)
      - 
      - 
      - 

    * - Swap Case (交换大小写)
      - 
      - 
      - 

    * - Upper Case (全部大写)
      - 
      - 
      - 

    * - Lower Case (全部小写)
      - 
      - 
      - 


Select
------------------------------------------------------------------------------

.. list-table:: Select
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Select All (选择全部)
      - 
      - 
      - 

    * - Expand Selection Line (选择光标所在行)
      - 
      - 
      - 

    * - Expand Selection to Word (选择光标所在的单词)
      - 
      - 
      - 

    * - Expand Selection to Paragraph (选择光标所在的段落)
      - 
      - 
      - 

    * - Add Previous Line (添加光标所在的 **上一行** 到 "已选择")
      - 
      - 
      - 

    * - Add Next Line (添加光标所在的 **下一行** 到 "已选择")
      - 
      - 
      -  

    * - Select Between Bracket (选择括号之间的内容)
      - 
      - 
      - 


Find
------------------------------------------------------------------------------

.. list-table:: Editing
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Find (搜索文本)
      - 
      - 
      - 

    * - Find in Directory (在目录中的所有文件中搜索文本)
      - 
      - 
      - 

    * - Replace (替换)
      - 
      - 
      - 

    * - Replace in Directory (在目录中的所有文件中替换文本)
      - 
      - 
      - 

    * - Find and Select Next (找到并选择 **下一个** 匹配)
      - 
      - 
      - 

    * - Find and Select Previous (找到并选择 **上一个** 匹配)
      - 
      - 
      - 

    * - Find and Select All (找到并选择全部)
      - 
      - 
      - 

    * - Find and Add Select Next (找到并将 **下一个** 匹配添加到已选项)
      - 
      - 
      - 

    * - Find and Multiple Edit (搜索到 **所有** 匹配后同时编辑)
      - 
      - 
      - 


Line
------------------------------------------------------------------------------

.. list-table:: General
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Insert Line After (在 **下面** 另起一行, 光标跳到 **下一行**)
      - 
      - 
      - 

    * - Insert Line Before (在 **上面** 另起一行, 光标跳到 **上一行**)
      - 
      - 
      - 

    * - Duplicate/Delete Line (复制/删除 该行)
      - 
      - 
      - 

    * - Indent/Unindent Line (增加/减少 该行缩进)
      - 
      - 
      - 

    * - Move Line Up/Down (移动该行)
      - 
      - 
      - 

    * - Join Lines (连接多行)
      - 
      - 
      - 

    * - Multiline Editing (多行同时编辑)
      - 
      - 
      - 

    * - Sort Lines (多行排序)
      - 
      - 
      - 


Navigation
------------------------------------------------------------------------------

.. list-table:: Navigation
    :widths: 10 10 10 10
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Previous/Next Tab (上/下 一个标签)
      - 
      - 
      - 

    * - Previous/Next Cursor (上/下 一个游标所在)
      - 
      - 
      - 

    * - Jump Between Bracket (在匹配的括号之间跳转)
      - 
      - 
      - 


Menu
------------------------------------------------------------------------------

.. list-table:: Menu
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Settings (设定)
      - 
      - 
      - 

    * - Pluggin (插件)
      - 
      - 
      - 


IDLE
------------------------------------------------------------------------------

.. list-table:: IDLE
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Copy Name (复制文件/文件夹名)
      - 
      - 
      - 

    * - Copy Absolute Path (复制绝对路径)
      - 
      - 
      - 

    * - Open in Explorer/Finder/File Manager (在文件浏览器中打开)
      - 
      - 
      - 

    * - Open in Default Application (使用默认的App打开)
      - 
      - 
      - 

    * - Run This File (运行当前编辑的脚本)
      - 
      - 
      - 

    * - Run Last File (运行上次运行的脚本)
      - 
      - 
      - 

    * - Select and Run (选择一个脚本运行)
      - 
      - 
      -

    * - Debug Last File (调试上次运行的脚本)
      - 
      - 
      - 

    * - Select and Debug (选择一个脚本调试)
      - 
      - 
      - 

    * - Open Command Line/Terminal (打开命令行)
      - 
      - 
      - 

    * - Fold/Unfold All Once (折叠/打开 代码一次)
      - 
      - 
      - 

    * - Fold/Unfold All Recursively (折叠/打开 全部代码)
      - 
      - 
      - 


Python
------------------------------------------------------------------------------

.. list-table:: Python
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Navigate to Previous/Next Method (上/下一个函数)
      - 
      - 
      - 

    * - Move Method/Class Up/Down (移动整个函数和类的位置)
      - 
      - 
      - 

    * - Find Usage (在项目中查找用例)
      - 
      - 
      - 

    * - Find Usage in File (在本文件中查找用例)
      - 
      - 
      - 

    * - Go to Declaration (到第一次的声明处)
      - 
      - 
      - 

    * - Go to Implementation (到实现处, 可能有多个)
      - 
      - 
      - 

    * - View Definition (快速查看定义)
      - 
      - 
      - 

    * - View Document (快速查看文档)
      - 
      - 
      - 

    * - Pep8 Reformat (Pep8风格化代码)
      - 
      - 
      - 

    * - Optimize Import (自动整理Import)
      - 
      - 
      - 

    * - Rename Variable (重命名变量)
      - 
      - 
      - 

    * - Bookmark Here (为某处添加书签, 以便快速浏览)
      - 
      - 
      - 

    * - Show ALl Bookmark (浏览所有的书签)
      - 
      - 
      - 


Template
------------------------------------------------------------------------------

.. list-table:: Template
    :widths: 20 20 20 20
    :header-rows: 1

    * - Description
      - Windows
      - MacOS
      - Linux

    * - Description
      - 
      - 
      - 

rst 用于共享的临时文件

用于共享的临时文件

To do list and time line for deliver Innovizio's Runtime Predict Model as a Product.rst
.. contents:: Table of Contents

To do list and time line for deliver Innovizio's Runtime Predict Model as a Product
===================================================================================


Evaluate Innovizio's work
-------------------------
1. Reproduce the result they claims to be.
2. Code, Data (Could be in database/S3/locally) are properly delivered.
3. Documents they give is easy to understand.

	**Timeline: Rudyi will give me the updated code on 5/25/2017, currently I can run the code, but we don't have complete data to reproduce all figures due to some S3, Database access problem. But it doesn't takes long**


Convert to Whiskerlabs Prod Code
--------------------------------


Code refactor
~~~~~~~~~~~~~
Innovizio's code is more likely a lab, scientific scripts going through the whole process. But in production, we need it:

1. **modulized**: data source, data clean, pre-process, post-process module should be separate.
2. **pluggable**: it should provide a framework style API to allow us point the data points to arbitrary data source input in very flexible way.
3. **testable**: debug and log is needed.
4. deployment as prod: a lots of efforts to do for deployment.
5. Python2/3 Compat: Innovizio doesn't write code in Python2/3 compatible style. It's for Python3. But AWS Lambda needs Python2. I will rewrite the code in Python2/3 compatible style.


Modules
~~~~~~~
This list includes all pluggable module we need for this project.

1. Raw Feature Data Processor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Get, clean, structured raw feature data from any kinds of data source. Raw data is those data points are directly observed, such as indoorTemp, outdoorTemp, runtime; Not derived feature.


2. Feature Data Constructor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Derive other features, resolve NA, error data.


3. Training Model and save
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The model should able to self-update. Basically we could train it every 2-week (this value varies) when we have new data feeds. And save the trained model on data persistance layer (Should be somewhere on cloud).


4. Predict/Test and parameters adjustment
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1. This module provides a simple, straightforward API for prediction usage.
2. Should have a utility method to evaluate the accuracy on arbitrarily big test dataset. This helps us dynamically adjust parameters.

	**Timeline: above 4 should able to be done in one week, once we are able to reproduce their result**


5. Deployment package
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- dependencies pack up and distributive
- other software resource prepare, s3, lambda, deployment scripts

	**Timeline: this part needs team work, time line is not predictable at this time.**


Documentation
-------------
It should have a nicer documentation for:

1. problem definition
2. solution, model explaination
3. features description
4. tech detail
5. experiment, guide for model adjustment

	**Timeline: 2-3 days**

rst 使用docker-compose设置哨兵

使用docker-compose设置哨兵

docker-compose.yml
version: '2'

volumes:
   pgdb:

services:
  redis:
    image: redis


  postgres:
    image: 'eeacms/postgres:9.5'
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DBNAME: sentry
      POSTGRES_DBUSER: sentry
      POSTGRES_DBPASS: sentry
    volumes:
     - pgdb:/var/lib/postgresql/data

  sentry:
    image: sentry:latest
    depends_on:
     - redis
     - postgres
    links:
     - redis
     - postgres
    ports:
     - 9000:9000
    environment:
      SENTRY_SECRET_KEY: verysecret
      SENTRY_POSTGRES_HOST: postgres
      SENTRY_DB_USER: postgres
      SENTRY_DB_PASSWORD: postgres
      SENTRY_REDIS_HOST: redis

  sentry_celery_beat:
    image: sentry:latest
    depends_on:
     - redis
     - postgres
    command: "sentry celery beat --pidfile=/tmp/celerybeat-sentry.pid"
    environment:
      SENTRY_SECRET_KEY: verysecret
      SENTRY_POSTGRES_HOST: postgres
      SENTRY_DB_USER: postgres
      SENTRY_DB_PASSWORD: postgres
      SENTRY_REDIS_HOST: redis

  sentry_celery_worker:
    image: sentry:latest
    depends_on:
     - redis
     - postgres
    command: "sentry celery worker"
    environment:
      SENTRY_SECRET_KEY: verysecret
      SENTRY_POSTGRES_HOST: postgres
      SENTRY_DB_USER: postgres
      SENTRY_DB_PASSWORD: postgres
      SENTRY_REDIS_HOST: redis
INSTALL.rst
In order to run this image do:
``docker-compose up -d`` to get all up.
On first run DB initialization and initial user setup is done like so:

First start a bash in the container: ``docker-compose exec sentry /bin/bash``.
Then, inside bash, do ``sentry upgrade`` wait until it asks you for an inital user. 
When finished ``exit`` the bash.

When in doubt check with ``docker-compose ps`` if all went fine.

rst 斯卡拉环境构筑

斯卡拉环境构筑

gistfile1.rst
################################################################################
Scala 開発環境構築手順
################################################################################

***********************************************************
前提条件
***********************************************************

* JDKがinstall済みであること
* java コマンドに環境変数Pathが通っていること


***********************************************************
sbt インストール
***********************************************************

http://www.scala-sbt.org/

Mac
    MacPorts だとバージョンが古いので homebrew を使用
    ``brew install sbt``

Windows
    http://www.scala-sbt.org/download.html から msi をDLして実行

Linux
    http://www.scala-sbt.org/download.html`

    からsbt-0.13.5.tgz をダウンロードして、適当な場所(hoge)に配置。hoge/sbt/binにPATHを通しておく。

    ``chmod u+x hoge/bin/sbt`` を実行


***********************************************************
IntelliJ IDEA インストール
***********************************************************

http://www.jetbrains.com/idea/download/index.html

公式からインストーラをDLして実行


***********************************************************
IntelliJ IDEA に Scala Plugin をインストール
***********************************************************

1. メニューの「File」 -> 「Settings」を選択
2. 「Plugins」 -> 「Browse Repositories」ボタンを押下して
   「Browse Repositories」ダイアログを開く
3. 右上の検索フォームに「scala」と入力して検索
4. 「Scala」と「SBT」をし、コンテキストメニューから「Download and Install」を実行
5. 「OK」を押下のち再び「OK」を押下
6. 再起動を要求されるので再起動


***********************************************************
IntelliJ IDEA に JavaSDKのパスを指定
***********************************************************

1. メニューの「File」->「Other Settings」-> 「Template Project Structure...」 を選択
2. 「Project Settings」 -> 「Project」 -> 「Project SDK」 の 「New」ボタンを押下
3. インストール済みJDKのパスを選択
4. 「OK」を押下


***********************************************************
conscript インストール
***********************************************************

Windows
=======================================

1. https://github.com/n8han/conscript から conscript runnable jar を DL
2. ``java -jar`` コマンドで DL した jar を実行
3. splash screen 下部のメッセージ部に 「Installed: ${インストールされたPath}」が表示されるまで待つ
4. splash screen を閉じる
5. ${インストールされたPath} に環境変数Pathを通す

Linux, Mac
=======================================

1. Terminal で ``curl https://raw.github.com/n8han/conscript/master/setup.sh | sh`` を実行 ::
2. $HOME/bin に環境変数Pathを通す


***********************************************************
giter8 インストール
***********************************************************

1. Terminal(コマンドプロンプト)で ``cs n8han/giter8`` を実行 ::


***********************************************************
giter8 にてプロジェクトテンプレートを導入
***********************************************************

1. Terminal(コマンドプロンプト)でプロジェクトフォルダを作成したいパスに移動
2. g8コマンドで任意のテンプレートを取得
   (handsonでは chrislewis/basic-project を使用) ::

       g8 chrislewis/basic-project

3. テンプレートに設定されているパラメータを入力


***********************************************************
プロジェクトの plugins.sbt に sbt-idea plugin の設定を記述
***********************************************************

1. プロジェクトフォルダ/project/plugins.sbt というファイルを作成し、下記の内容を記述 ::

       resolvers += "sbt-idea-repo" at "http://mpeltonen.github.com/maven/"
       
       addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.0.0")

2. **(Optional)** プロジェクトフォルダ/.gitignore というファイルを作成し、下記の内容を記述 ::

       .DS_Store
       Thumnail.db
       target/
       lib_managed/
       src_managed/
       project/boot/

3. Terminal(コマンドプロンプト)でカレントディレクトリをプロジェクトフォルダに移動
4. ``sbt`` 実行
5. ``gen-idea`` 実行


***********************************************************
IntelliJ IDEA でプロジェクトを開く
***********************************************************

1. メニューの「File」 -> 「Open Project...」を選択
2. プロジェクトフォルダを選択


***********************************************************
IntelliJ IDEA の SBT Plugin に sbt のパスを設定
***********************************************************

1. メニューの「File」 -> 「Settings」を選択
2. 「SBT」 -> 「SBT Launcher JAR file」でインストール済みの sbt-launch.jar を指定

  * brew で sbt をインストールした場合 ``/usr/local/Cellar/sbt/0.11.2/libexec/sbt-launch.jar`` にインストールされる

3. 「OK」を押下


***********************************************************
IntelliJ IDEA に Scala Compiler を指定
***********************************************************

1. メニューの「File」-> 「Settings」を選択
2. 「Project Settings」 -> 「Compiler」 -> 「Scala Compiler」を選択
3. 「Compiler library」に ``sscala-2.9.1`` を指定
4. 「OK」を押下


***********************************************************
sbt-idea プラグインの不具合?対応
***********************************************************

1. メニューの「File」 -> 「Project Structure...」を選択
2. 「Project Settings」 -> 「Modules」 -> 「default-XXXXXX」 -> 「Dependencies」タブ選択
3. ``org.scala-lang_scala-library_2.9.1`` の Scope が 「Test」 になっているのを 「Compile」 に変更
4. 「OK」を押下


rst 使用ServerPilot安装Comodo PositiveSSL证书的步骤。

使用ServerPilot安装Comodo PositiveSSL证书的步骤。

install-comodo-ssl-cert-with-serverpilot.rst
Setting up a SSL Cert from Comodo with ServerPilot
=================================

I use `Google Domains <https://domains.google/#/>`_ as a registrar, `DigitalOcean.com <https://m.do.co/c/968c2d6ff2e5>`_ for hostings and  `Comodo <https://comodosslstore.com/>`_ for SSL Certs.

These are the steps I went through to set up an SSL cert.

Purchase the cert
-----------------

Prior to purchasing a cert, you need to generate a private key, and a CSR file
(Certificate Signing Request). You'll be asked for the content of the CSR file
when ordering the certificate.

::

    openssl req -new -newkey rsa:2048 -nodes -keyout example_com.key -out example_com.csr

This gives you two files:

* ``example_com.key`` -- your Private key. You'll need this later to configure ngxinx.
* ``example_com.csr`` -- Your CSR file.

Now, purchase the certificate [1]_, follow the steps on their site, and you should soon get an 
email with your *PositiveSSL Certificate*. It contains a zip file with the following:

* Root CA Certificate - `AddTrustExternalCARoot.crt`
* Intermediate CA Certificate - `COMODORSAAddTrustCA.crt`
* Intermediate CA Certificate - `COMODORSADomainValidationSecureServerCA.crt`
* Your PositiveSSL Certificate - `www_example_com.crt` (or the subdomain you gave them)

Install the Commodo SSL cert
----------------------------

Combine everything for nginx [2]_:

1. Combine the above crt files into a bundle (the order matters, here)::

    cat www_example_com.crt COMODORSADomainValidationSecureServerCA.crt  COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > ssl-bundle.crt

2. Store the bundle wherever nginx expects to find it::

    mkdir -p /etc/nginx/ssl/example_com/
    mv ssl-bundle.crt /etc/nginx/ssl/example_com/

3. Ensure your private key is somewhere nginx can read it, as well.::

    mv example_com.key /etc/nginx/ssl/example_com/

4. Make sure your nginx config points to the right cert file and to the private
   key you generated earlier::

    server {
        listen 443;

        ssl on;
        ssl_certificate /etc/nginx/ssl/example_com/ssl-bundle.crt;
        ssl_certificate_key /etc/nginx/ssl/example_com/example_com.key;

        # side note: only use TLS since SSLv2 and SSLv3 have had recent vulnerabilities
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

        # ...

    }

6. Restart nginx::

    service nginx-sp restart