python static 和 Template的总结

Template

所有的文件夹里面的Templates里面的文件最后都会结合到一个Template里面,所以在app里面定义的Templates文件。所以如果定义app里面的跟app自己相关的template,最好的方式是把Template文件放置在新建的和APP同名的文件夹里面。
如果是使用createPROJECT创建的目录,Template使用到根目录。

2018/6/18 posted in  python

django-channels 入门

基本的流程组件

routing.py

添加websocket的基本监听路径,所有的websocket的相关内容放置在这个路径之下

在routing之中使用ProtocolTypeRouter来定义相应的application入口,这个是2.0引入的新特性,在第一个版本中不这么使用

# mysite/routing.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import chat.routing

application = ProtocolTypeRouter({
    # (http->django views is added by default)
    'websocket': AuthMiddlewareStack(
        URLRouter(
            chat.routing.websocket_urlpatterns
        )
    ),
})

外层中间件使用ProtocolTypeRouter,并结合使用AuthMiddlewareStack中间件来将routing文件指定到内部文件。

# chat/routing.py
from django.conf.urls import url

from . import consumers

websocket_urlpatterns = [
    url(r'^ws/chat/(?P<room_name>[^/]+)/$', consumers.ChatConsumer),
]

内部文件也使用类似urlpatterns的模式来进行,这里是讲这个chat 下面room_name的所有都制定到ChatConsumer里面。可以发现这里制定的是Consumer对象而不是具体的一个方法。这个和老版本的还是有一些区别的。

在setting中需要加入这个application的配置项

# mysite/settings.py
# Channels
ASGI_APPLICATION = 'mysite.routing.application'

Consumer

在定义WebSocket的时候最后加上/ws/的路径,这样能够更好地区分Http请求和webscoket请求,从而更好进行优化。同时也更方便在部署的时候让nginx更好的将不同的目录给不同的部件去解析。WSGI Server使用 Gunicorn + Django 来解析Http请求;ASGI Server 可以使用Daphne+Channels来解析WebSocket请求。

对于小型的网站可以使用Daphne Server就可以同时解析HTTP和socket请求,从而不需要划分。

# chat/consumers.py
from channels.generic.websocket import WebsocketConsumer
import json

class ChatConsumer(WebsocketConsumer):
    def connect(self):
        self.accept()

    def disconnect(self, close_code):
        pass

    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        self.send(text_data=json.dumps({
            'message': message
        }))

这个是最基本同步连接请求,从同步端接收请求等

同步请求的Consumer如下

# chat/consumers.py
from channels.generic.websocket import AsyncWebsocketConsumer
import json

class ChatConsumer(AsyncWebsocketConsumer):
    async def connect(self):
        self.room_name = self.scope['url_route']['kwargs']['room_name']
        self.room_group_name = 'chat_%s' % self.room_name

        # Join room group
        await self.channel_layer.group_add(
            self.room_group_name,
            self.channel_name
        )

        await self.accept()

    async def disconnect(self, close_code):
        # Leave room group
        await self.channel_layer.group_discard(
            self.room_group_name,
            self.channel_name
        )

    # Receive message from WebSocket
    async def receive(self, text_data):
        text_data_json = json.loads(text_data)
        message = text_data_json['message']

        # Send message to room group
        await self.channel_layer.group_send(
            self.room_group_name,
            {
                'type': 'chat_message',
                'message': message
            }
        )

    # Receive message from room group
    async def chat_message(self, event):
        message = event['message']

        # Send message to WebSocket
        await self.send(text_data=json.dumps({
            'message': message
        }))
2018/6/5 posted in  python

pycharm 配置导入django项目

我一般的做法是通过命令行git clone ,然后在手动创建venv ,最后再导入

virtualenv -p /usr/local/bin/python3.6 

新建项目

使用打开文件夹来创建项目,打开文件夹的目录最好定位到项目内部目录中去,不要导入venv,否则后面打开文件什么的都很麻烦

配置django工程

直接open的文件夹是无法成为django工程的,需要手动导入django工程
打开preference,或者使用快捷键 cmd + ,

1. 配置venv

直接选择到已有virtualenv环境即可

2. 配置django framework

配置运行时环境

完成后即可。

2018/5/24 posted in  python

redash 新版本研究

测试环境 61.183.247.105

  1. 安装 还是可以使用ubuntu的安装脚本安装,这个安装脚本比以前做的好一些了,没什么bug,但是不能在virtualenv下面安装,否则包找不到,这个后面可以研究一下如何处理
  2. 安装好之后实际是可以使用的
  3. 如果要修改前台页面,需要重新进行npm build 。 方法就是首先到版本的目录,然后执行npm run install。执行npm install的时候记得最好把github的hosts配上,不然可能下不到会失败。然后完成后再执行npm run build就可以把前端build出来了,build的内容会在clinet/dist目录下。如果要修改文件需要重新build才可以生效。supervisor使用的是dist文件夹。
  4. 如果执行一次npm install 失败,不要修改后继续执行,最好先删除npm文件,首先rm -rf node_modules 然后再执行 npm install

可以研究一下要搞的几个东西

  • 开发环境配置——整理一个更好的python开发环境模式
  • 尝试把echarts插件引入到visualization组件中去
  • docker配置
  • 整理成docker开发环境

开发环境整理

  1. 可以按照安装脚本整理一套,然后自己手动启动webserver 、Celery、webpack,把这三个搞好可以试着跑起来,按照安装的模式来整理开发环境

开发梳理

redash 使用了 flask、 angularJS

redash 代码结构研究

  1. client —— 存储所有的前台内容
    1. app —— 存放所有的前台源码,包含HTML、js
      1. assets/ —— 存放所有的css、fonts、images
      2. components/ —— 大部分组件的页面都存放在这里。这里和pages的区别是这里大多存的是一些公共组件,而不是主题页面
      3. config/ ——存放基本配置,包含angularJS总路由,样式表文件配置等
      4. directives/ —— 基本配置统一放在这里
      5. filters/
      6. lib/
        1. pagination/ —— 分页组件
        2. sortable/ —— 排序组件
        3. visualizations —— 可视化插件
      7. pages/
        1. admin/ ——首页用户名下面的system status页面的Admin管理页面,包含system status系统状态、queries queue查询队列、outdated queries过期查询队列。
        2. alert/ ——首页菜单alert页面
        3. alerts-list/
        4. dashboards/
        5. data-sources/
        6. destinations/
        7. groups/
        8. home/
        9. queries/
        10. queries-list/
        11. query-snippets/
        12. users/
      8. services/ —— 相应的js服务部分
      9. visualizations/ —— 可视化相关部分
    2. dest —— 存放所有的webpack打包后的页面内容
  2. migration —— 存放所有的数据库更新内容
  3. redash —— 存储redash的后端部分,所有的py文件都在这里面,这里的话最好还是要详细研究一下flask在来修改,跟django还是有一些区别的。
  4. test —— 存储测试内容

从词云组件开始研究visualization

wordcloud

开发模式

redash也存在开发模式,实际上在package.json已经配置了,在webpack.config.js里面也进行了相关的配置

package.json里面的配置

"scripts": {
    "start": "webpack-dev-server",
    "build": "rm -rf ./client/dist/ && NODE_ENV=production node node_modules/.bin/webpack",
    "watch": "webpack --watch --progress --colors -d"
  },

start 用于 run start 来启动web pack服务。

build用于重新发布

watch用于开发环境下修改文件后的直接发布,所见即所得。

每次build的时间比较久,如果每次开发修改一点点都需要build的话,那将会很浪费时间,所以使用watch模式,每次有修改之后会自动进行发布和编译,并且响应速度较快。

使用的方法: npm run watch

运行启动后,修改相关文件会自动进行编译,只需要刷新页面就能生效,最好是强制刷新。

访问数据库

root@williiiam-dev:/opt/redash/redash.3.0.0.b3134# sudo -u redash psql

配置到navicat 远程连接

配置与连接
首先,在pgdata(也就是在安装pg时指定的存放数据的文件见中)文件夹中,找到pg_hba.conf文件,并写入下面的内容:

$ host    all        all         0.0.0.0/0       trust

接着,在pgdata文件夹中,找到postgresql.conf为文件,并修改下面的内容:

$ listen_addresses = '*'     #允许任何的ip地址监听,并保存

最后,重新启动PostgreSQL数据库,然后在Navicat中进行连接配置,该步骤省略,相信使用过功该工具的读者都知道该怎么配置。

$ ${PG_HOME}/bin/pg_ctl restart -D ${PGDATA}   #重新启动pg数据库
2018/2/13 posted in  python

亲测只能使用python2.7版本来安装redash

安装npm

apt-get install nodejs
apt-get install npm

#如果不执行这个会报错
apt-get install nodejs-legacy

安装redis


安装postgresql

安装问题

Successfully built gspread impyla MySQL-python oauth2client pyhive pymongo vertica-python dql sasl thrift thrift-sasl cassandra-driver memsql uritemplate future msgpack-python wraptor
Installing collected packages: uritemplate, pyasn1, pyasn1-modules, rsa, oauth2client, google-api-python-client, gspread, thrift, impyla, influxdb, MySQL-python, future, pyhive, pymongo, pyOpenSSL, vertica-python, urllib3, msgpack-python, td-client, pymssql, jmespath, docutils, botocore, dynamo3, pyparsing, dql, sasl, thrift-sasl, futures, cassandra-driver, wraptor, memsql, atsd-client, simple-salesforce, s3transfer, boto3, monotonic, tenacity, PyAthena, certifi
Found existing installation: pyOpenSSL 17.5.0
Uninstalling pyOpenSSL-17.5.0:
Successfully uninstalled pyOpenSSL-17.5.0
Successfully installed MySQL-python-1.2.5 PyAthena-1.2.1 atsd-client-2.0.12 boto3-1.5.26 botocore-1.5.72 cassandra-driver-3.11.0 certifi-2018.1.18 docutils-0.14 dql-0.5.24 dynamo3-0.4.7 future-0.16.0 futures-3.2.0 google-api-python-client-1.5.1 gspread-0.6.2 impyla-0.10.0 influxdb-2.7.1 jmespath-0.9.3 memsql-2.16.0 monotonic-1.4 msgpack-python-0.4.8 oauth2client-3.0.0 pyOpenSSL-16.2.0 pyasn1-0.4.2 pyasn1-modules-0.2.1 pyhive-0.3.0 pymongo-3.2.1 pymssql-2.1.3 pyparsing-2.1.4 rsa-3.4.2 s3transfer-0.1.12 sasl-0.2.1 simple-salesforce-0.72.2 td-client-0.8.0 tenacity-4.8.0 thrift-0.11.0 thrift-sasl-0.3.0 uritemplate-0.6 urllib3-1.22 vertica-python-0.5.1 wraptor-0.6.0
Traceback (most recent call last):
File "/opt/redash/redash.3.0.0.b3134/manage.py", line 6, in
from redash.cli import manager
File "/opt/redash/redash.3.0.0.b3134/redash/__init__.py", line 5, in
import redis
ImportError: No module named redis

需要安装

(redashenv) root@williiiam-dev:/opt/redash/redash/setup/ubuntu# pip install redispy
Collecting redispy
Downloading redispy-3.0.0-py2.py3-none-any.whl (64kB)
100% |████████████████████████████████| 71kB 177kB/s
Installing collected packages: redispy
Successfully installed redispy-3.0.0

解决方案

在requirements.txt中增加引入 redispy==3.0.0

2018/1/12 posted in  python

虚拟环境 — Python最佳实践指南

虚拟环境是一个将不同项目所需求的依赖分别放在独立的地方的一个工具,它给这些工程创建虚拟的Python环境。它解决了“项目X依赖于版本1.x,而项目Y需要项目4.x”的两难问题,而且使你的全局site-packages目录保持干净和可管理。

比如,你可以工作在一个需求Django 1.3的工程,同时维护一个需求Django 1.0的工程。

virtualenv 是一个创建隔绝的Python环境的工具。virtualenv创建一个包含所有必要的可执行文件的文件夹,用来使用Python工程所需的包。

通过pip安装virtualenv:

$ cd my_project_folder
$ virtualenv venv

virtualenv venv 将会在当前的目录中创建一个文件夹,包含了Python可执行文件,以及 pip 库的一份拷贝,这样就能安装其他包了。虚拟环境的名字(此例中是 venv )可以是任意的;若省略名字将会把文件均放在当前目录。

在任何你运行命令的目录中,这会创建Python的拷贝,并将之放在叫做 venv 的文件中。

你可以选择使用一个Python解释器:

$ virtualenv -p /usr/bin/python2.7 venv

这将会使用 /usr/bin/python2.7 中的Python解释器。

$ source venv/bin/activate

当前虚拟环境的名字会显示在提示符左侧(比如说 (venv)你的电脑:你的工程 用户名$)以让你知道它是激活的。从现在起,任何你使用pip安装的包将会放在 venv 文件夹中,与全局安装的Python隔绝开。

像平常一样安装包,比如:

这将会回到系统默认的Python解释器,包括已安装的库也会回到默认的。

要删除一个虚拟环境,只需删除它的文件夹。(要这么做请执行 rm -rf venv

然后一段时间后,你可能会有很多个虚拟环境散落在系统各处,你将有可能忘记它们的名字或者位置。

运行带 --no-site-packages 选项的 virtualenv 将不会包括全局安装的包。这可用于保持包列表干净,以防以后需要访问它。(这在 virtualenv 1.7及之后是默认行为)

为了保持你的环境的一致性,“冷冻住(freeze)”环境包当前的状态是个好主意。要这么做,请运行:

$ pip freeze > requirements.txt

这将会创建一个 requirements.txt 文件,其中包含了当前环境中所有包及各自的版本的简单列表。你可以使用 “pip list”在不产生requirements文件的情况下,查看已安装包的列表。这将会使另一个不同的开发者(或者是你,如果你需要重新创建这样的环境)在以后安装相同版本的相同包变得容易。

$ pip install -r requirements.txt

这能帮助确保安装、部署和开发者之间的一致性。

最后,记住在源码版本控制中排除掉虚拟环境文件夹,可在ignore的列表中加上它。

virtualenvwrapper 提供了一系列命令使得和虚拟环境工作变得愉快许多。它把你所有的虚拟环境都放在一个地方。

安装(确保 virtualenv 已经安装了):

$ pip install virtualenvwrapper
$ export WORKON_HOME=~/Envs
$ source /usr/local/bin/virtualenvwrapper.sh

( virtualenvwrapper 的完整安装指引.)

对于Windows,你可以使用 virtualenvwrapper-win

To install (make sure virtualenv is already installed): 安装(确保 virtualenv 已经安装了):

$ pip install virtualenvwrapper-win

在Windows中,WORKON_HOME默认的路径是 %USERPROFILE%Envs 。

这会在 ~/Envs 中创建 venv 文件夹。

或者,你可以创建一个项目,它会创建虚拟环境,并在 $PROJECT_HOME 中创建一个项目目录。当你使用 workon myproject 时,会 cd -ed 到项目目录中。

virtualenvwrapper 提供环境名字的tab补全功能。当你有很多环境,并且很难记住它们的名字时,这就显得很有用。

workon 也能停止你当前所在的环境,所以你可以在环境之间快速的切换。

  • lsvirtualenv
  • 列举所有的环境。
  • cdvirtualenv
  • 导航到当前激活的虚拟环境的目录中,比如说这样你就能够浏览它的 site-packages
  • cdsitepackages
  • 和上面的类似,但是是直接进入到 site-packages 目录中。
  • lssitepackages
  • 显示 site-packages 目录中的内容。

virtualenvwrapper 命令的完全列表

有了 virtualenv-burrito ,你就能使用单行命令拥有virtualenv + virtualenvwrapper的环境。

当你 cd 进入一个包含 .env 的目录中,就会 autoenv 自动激活那个环境。

使用 brew 在Mac OS X上安装它:

在Linux上:

$ git clone git://github.com/kennethreitz/autoenv.git ~/.autoenv
$ echo 'source ~/.autoenv/activate.sh' >> ~/.bashrc

虚拟环境 — Python最佳实践指南

2017/2/28 posted in  python

ubuntu redash 开发环境配置

配置流程

1. 安装docker

2. 安装shadowsocks

由于在github上面下载代码总是出现下载失败的情况,而且下载一个东西总是很慢,我们还是开一下VPN吧。

具体安装方法可以参考 ubuntu 下使用 shadowsocks

3. 安装git ,并克隆代码

安装github,克隆代码到本地。

4. 安装docker-compose

5. 安装nodejs

curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
sudo apt-get install -y nodejs

6. docker-compose up

执行docker-compose up即可

记得提前执行 pip --default-timeout=100000 install -U PIP 将超时时间设置长一些。

2017/2/24 posted in  python

隐形url跳转实现

显性url和隐形url

显性/隐性URL转发流程
解析
1、域名管理员解析heytool.com,选择隐性或者显性url转发,记录值写上
http://www.heytool.com 或者你想要跳转的地方
2、dns提供商将heytool.com解析到他们的服务器上,并且这台服务器上配置了虚拟主机heytool.com
2.1 显性URL跳转:配置里将所有到这的请求跳转到www.heytool.com.
2.2 隐性URL转发:站点里面的index.html面加上iframe,在里面嵌套www.heytool.com.所以不管你怎么点链接,url地址栏都不会变化.除非你的连接是打开新页面
访问

  1. 用户在浏览器中输入heytool.com
  2. 浏览器做DNS解析,返回54.248.82.230(延续我的例子),浏览器访问54.248.82.230上的heytool.com
    2.1 显性URL转发:服务器将你跳转到www.heytool.com
    2.2 隐性URL转发:服务器返回一个嵌套www.heytool.com地址的index.html文件,浏览器再次去访问www.heytool.com,并且内容嵌套在index.html里,所以用户就看不到有任何跳转.(不推荐)

隐形url配置方法

在nginx中配置

 server {
        listen       80;
        server_name  ***.***.com;

        location / {
                alias /opt/agent/;
                index index.html;
        }
    }

配置index文件

<HTML><frameset rows="100%" ><frame src="https://www.hansap.com/agent/713"></frameset></HTML>

这样在访问网站的时候,会在内部的url中隐形跳转到内部页面。

多页面的自动化配置

针对以后的多页面,可以采用自动化配置

  1. 配置文件路径,在类似_opt_agent路径下自动化添加index.html文件;
  2. 在文件中动态填入内容,其中用户需要填入相应的需要跳转的url 地址;
  3. 配置单独的nginx配置文件;
  4. 每次有新的代理商进入的时候,追加配置文件内容;
  5. 添加相应的server_name 为代理商提供的域名;
  6. 添加location里面相应的目录,到我们之前配置的index.html文件上;
  7. nginx -s reload重启一下nginx就可以生效了。

tips

  1. 在html中可以加上head里面的title 和 Keyword相关的内容
  2. 在html中加上相关的统计代码,统计服务器访问信息。
2017/1/23 posted in  python

sublime 3 插入行号

  • release

在用sublime生成一些脚本的时候,会用到生成行号的操作,使用Insert Nums这个插件可以实现。

安装InsertNums

使用 cmd+shift+p 打开sublime快捷管理器

输入install package ,等待一下之后会弹出新窗口,

然后输入Insert Nums,完成后就可以开始安装

使用InsertNums

同样的输入cmd+shift+p 打开快捷管理器

输入Insert num 便可以使用,同时可以看到下面支持多种方式的 比如 200:5 ,其中200代表其实数,5代表步长。

结合cmd+shift+l 使用能够起到更好的效果。

2016/12/20 posted in  python

ubuntu 安装redash

  • release

安装临时插件

apt-get update
apt-get install git 
git clone https://github.com/yourwilliam/redash

$ sudo apt-get install python-pip python-dev build-essential 
$ sudo pip install --upgrade pip 
$ sudo pip install --upgrade virtualenv 

换源

1.临时换源

临时换源只在某一条命令中生效,只要在命令中加上”-i“,指定使用的源即可

pip install scrapy -i

2.永久换源

要是想彻底将pip的源换掉,只要在pip的配置文件(~_.pip_pip.conf)中增加

[global]
index-url=
http://pypi.douban.com/simple

3.一些国内的pip源

http://pypi.douban.com/simple  #豆瓣
http://pypi.hustunique.com/simple  #华中理工大学
http://pypi.sdutlinux.org/simple  #山东理工大学
http://pypi.mirrors.ustc.edu.cn/simple  #中国科学技术大学

pip 测试可用的换源方式,一定要使用这一个,而且一定要用https

pip install wagtail -i https://pypi.douban.com/simple

初步安装

root@ubuntu:/opt/redash# virtualenv redashenv

root@ubuntu:/opt/redash# source redashenv/bin/activate

(redashenv) root@ubuntu:/opt/redash# sudo apt-get install libpq-dev

(redashenv) root@ubuntu:/opt/redash/setup/ubuntu# cd /opt/
(redashenv) root@ubuntu:/opt# chmod 777 redash/

(redashenv) root@ubuntu:/opt/redash/setup/ubuntu# sh bootstrap.shd

会报一个这个错

Creating redash postgres user & database.
Traceback (most recent call last):
File "_opt_redash_redash.0.11.1.b2095_manage.py", line 7, in
from flask_script import Manager
ImportError: No module named flask_script

修改

vi /opt/redash/redash.0.11.1.b2095/manage.py 
#!/opt/redash/redashenv/bin/python

再次执行安装

还会报一个错:

peewee.ProgrammingError: relation "organizations" does not exist
LINE 1: ...", "t1"."name", "t1"."slug", "t1"."settings" FROM "organizat…

要重新配置数据库

(redashenv) root@ubuntu:/opt/redash/setup/ubuntu# su - postgres
psql

ostgres=# drop database redash;
DROP DATABASE
postgres=# drop user redash;
DROP ROLE

退出 继续安装

在起一次就能成功了,显示

2016-11-20 14:47:08 (68.7 MB_s) - ‘_etc_nginx_sites-available/redash’ saved [453/453]

* Restarting nginx nginx                                                                     [ OK ]

就OK了。

修改数据库权限

创建root 用户,给予权限

(redashenv) root@ubuntu:/opt/redash/setup/ubuntu# su - postgres
postgres@ubuntu:~$ psql

postgres=# create user root;
postgres=# ALTER ROLE root SUPERUSER;
ALTER ROLE

启动redash_server

还是会报错:

(redashenv) root@ubuntu:/opt/redash/redashenv/bin# mkdir /opt/redash/logs
(redashenv) root@ubuntu:/opt/redash/redashenv/bin# supervisord -c /opt/redash/setup/ubuntu/files/supervisord.conf

(redashenv) root@ubuntu:/opt/redash/redashenv/bin# mkdir /opt/redash/logs
(redashenv) root@ubuntu:/opt/redash/redashenv/bin# supervisord -c /opt/redash/setup/ubuntu/files/supervisord.conf
(redashenv) root@ubuntu:/opt/redash/redashenv/bin# supervisorctl restart redash_server
redash_server: stopped
redash_server: started

维护redash参考 http://docs.redash.io/en/latest/usage/maintenance.html

这还没完

仔细研究了一下,从脚本可以看到 ,是用的redash的账号来启动的。 这里我的安装是改成了使用root来控制。
后面在来研究怎么样用redash账号搞定。

在执行restart all的时候可以看到实际上可以看到redash_celery 是没有起起来的,这样可以看到的结果是感觉redash可以登陆,可以添加使用,但是数据是查不出来的,随便执行一个QUERY就可以看到。这是要控制celery的话需要再配置

从报错可以看到

Running a worker with superuser privileges when the
worker accepts messages serialized with pickle is a very bad idea!

If you really want to continue then you have to set the C_FORCE_ROOT
environment variable (but please think about this before you do).

User information: uid=0 euid=0 gid=0 egid=0

就是celery不推荐使用root来执行,需要修改

网上有几种办法,一种是使用 export C_FORCE_ROOT=‘true’ 这种是不管用的

另外一种是添加

platforms.C_FORCE_ROOT = True #添加这一行

这个是可以的,需要把这个添加的work中

vi _opt_redash_redash.0.11.1.b2095_redash/worker.py

http://redn.net/content/解决celery在root用户下启动问题cforceroot-environment

然后再执行:

(redashenv) root@ubuntu:/opt/redash/redashenv/bin# supervisorctl restart all
redash_server: stopped
redash_celery: started
redash_server: started
redash_celery_scheduled: started

测试后方可。

至此ubuntu版本的全部安装完毕

邮件配置:

在.env环境中配置 _opt_redash/.env 中

export REDASH_STATIC_ASSETS_PATH="../rd_ui/dist/"
export REDASH_LOG_LEVEL="INFO"
export REDASH_REDIS_URL=redis://localhost:6379/0
export REDASH_DATABASE_URL="postgresql://redash"
export REDASH_COOKIE_SECRET=veryverysecret
export REDASH_MAIL_SERVER="smtp.hansap.com"
export REDASH_MAIL_PORT="25"
export REDASH_MAIL_USE_TLS="false"
export REDASH_MAIL_USE_SSL="false"
export REDASH_MAIL_USERNAME="hansap@hansap.com"
export REDASH_MAIL_PASSWORD="Fire@123"
export REDASH_MAIL_DEFAULT_SENDER="hansap@hansap.com"
export ERDASH_HOST="http://bi.hansap.com"

配置完成后可以测试

(redashenv) root@ubuntu:/opt/redash/current# bin/run ./manage.py send_test_mail

注意一定要在current下测试,而且一定要按照这个目录来执行。

执行完成后重启

(redashenv) root@ubuntu:/opt/redash/redashenv/bin# supervisorctl restart all

配置完成

新版本

需要在全局路径(非virtualENV环境下装上redis依赖包才可以 'pip install redis')

2016/12/20 posted in  python

NodeBox Strategy

循环的使用

循环变量

size(400,400)

fill(0,0.6,0.9,0.1)
stroke(0,0.6,0.9)
strokewidth(0.25)

for i in range(100):
    fill(random(0.0,1.0),random(0.0,1.0),random(0.0,1.0),0.1)
    x = random(WIDTH)
    y = random(HEIGHT)
    r = random(50,100)
    oval(x,y,r,r)

执行结果:

这个就不多说了,其实在前面都有介绍,主要是将循环和随机结合。

函数

size(400,400)

def flower(x,y):
    fill(random(0.5,1),random(0.5,1),random(0.5,1))
    stroke(0.2)
    strokewidth(1)
    
    transform(CORNER)
    translate(x,y)
    
    for i in range(10):
        rotate(360/10)
        line(0,0,15,15)
        oval(10,10,10,10)
    reset()
    
for i in range(60):
    flower(random(WIDTH),random(HEIGHT))

这里主要处理的是函数关系的调用。也不需要多讲

Library 包

Nodebox同时可以使用各种Library包,用这些Library包来扩展整体的能力。

要安装扩展包的时候只需要将扩展包下载,然后让道NodeBox的目录,在使用的时候调用ximport()就可以了

同时也可以使用ximport来引入其他的python包。

list = [1, 2, 3, 4, 5]
rnd = ximport("random")
rnd.shuffle(list) 
print list  
>>> [3, 4, 1, 5, 2]
2016/8/22 posted in  python

NodeBox Data

NodeBox 变量

预置的变量

NodeBox 配置了一系列的预置变量,这些变量只能读,而不能写。

WIDTH: 绘画区域的宽度,可以通过size(300,300)来定义

HEIGHT: 绘画区域的高度,可以通过size(300,300)来定义

PAGENUM: 在多页的导出中可以显示当前页的页码

FRAME: 在动画中显示当前帧数

下面一些能够用在交互中:

MOUSEX: 当前鼠标的水平坐标

MOUSEY: 当前鼠标的垂直坐标

mousedown: 当鼠标按下时,值为True

keydown: 当相关的key按下时,值为True

key: 最后一个按下的Key值

keycode: 上一个按键的值,整数的形式。

KEY_UP, KEY_DOWN_ KEY_LEFT, KEY_RIGHT, KEY_BACKSPACE contain the keycodes for the arrow keys and the backspace key.

Node 输入参数

var("label",TEXT)
var("x",NUMBER,50,1,100)
var("y",NUMBER,50,1,100)

text(label,x,y)

var变量的参数

var(name, NUMBER, default, min, max)
var(name, TEXT, default="hello")
var(name, BOOLEAN)
var(command, BUTTON)

NodeBox 列表

列表

NodeBox中的列表和代码中的列表是类似的,同样是以0为起始索引。实际上就是使用了python中的列表类型。

列表的一个很有趣的demo:

size(200,200)
words = ["Lists", "are", "fun"]
colors = [color(1,0,0), color(1,1,1), color(0,0,0)]
 
for i in range(40):
 
    x = random(WIDTH)
    y = random(HEIGHT)
    rotate(random(360))
    fontsize(random(10,100))
 
    fill(choice(colors))
    text(choice(words), x, y)

这个例子从world和colors中随机选择颜色的字体,在页面上随机放置。
形成的图片如下:

多次运行可以形成不同的图片样式,这种很多海报会死用类似的方式,用杂乱的排版来形成比较好看的广告。

字典值:

字典值dictionaries ,直接使用python的数据类型。

String 字符串变量

String 是一个列表

其实这也是python的基本语法的例子,不过给出了一个demo还是挺好的,作为相应的例子,把几个方法也给我们展示了一下。

size(400,400)

fill(0.2)
rect(0,0,WIDTH,HEIGHT)

fill(1)
stroke(0.2)
strokewidth(1)
font("Zapfino")

for i in range(80):
    fontsize(random(400))
    rotate(random(360))
    
    chars = "abcdefghijklmnopqrstuvwxyz"
    
    p = textpath(choice(chars), random(WIDTH), random(HEIGHT))
    
    drawpath(p)

这里用到几个比较重要的概念,使用choice(chars)说明chars是一个列表结构。
textpath代表了文本的描边,使用drawpath 可以对描边进行绘画。

运行结果如下:

String的一些相关方法

下面是String的一些相关方法

  • string.upper(): returns the string in uppercase.
  • string.lower(): returns the string in lowercase.
  • string.capitalize(): returns the string with the first character capitalized.
  • string.find(text, start=0): returns the index position of text in the string.
  • string.replace(old, new): replaces all old text in the string with new
  • string.split(): returns the string as a list of words.
  • string.join(list): concatenates a list of words.

这里也基本上都是python的一些基本方法

文件读入

size(500,500)

str = open("Applications/NodeBox/mo.txt").read()
str = str.decode("utf-8")

fill(0.2)

rect(0,0,WIDTH,HEIGHT)

fill(1)

font(u"黑体",13)
text(u"中国体育代表团", 20,30)

font(u"兰亭黑-简",11)
lineheight(1.4)
text(str,20,50,width=450)

使用文件读入方式来来读入相应的字符串。 如果为中文的话,需要使用decode一次utf-8。

最后的执行结果

2016/8/20 posted in  python

django sitemap 框架

sitemap的作用

通过这个站点可以查看一下自己网站的sitemap,从而可以查询到相关的浏览器索引项目http://www.sitemap-xml.org/

如果主页没有到index.html,而是跳转到其他的页面,可能2会出现无法索引的情况。

Sitemap 可方便网站管理员通知搜索引擎他们网站上有哪些可供抓取的网页。基本上所有的搜索引擎都集成了各自的sitemap爬取方式供浏览器来调用。每个公司也设置了自己的sitemap格式形式,但是基本还是类似的。

sitemap 的 django实现

在setting.py的INSTALLED_APPS 里面添加django.contrib.sitemaps

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'django.contrib.sites',
        'django.contrib.sitemaps',
        'django_comments',
        'blog',
        'pagination',
        'tagging',
        'mshow',
        'pagedown',
        'markdown_deux',
    ]

修改相关的Templates配置

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR,'templates').replace('\\', '/'),],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                    'django.core.context_processors.debug',
                    'django.core.context_processors.i18n',
                    'django.core.context_processors.media',
                    'django.core.context_processors.request',
                ],
            },
        },
    ]

添加urls 到根目录以及相应的sitemaps

    sitemaps = {
        'blog': GenericSitemap({'queryset': Entry.objects.all(), 'date_field': 'publication_date'}, priority=0.6),
    }
    urlpatterns = [
        url(r'^$', views.blog, name="index"),
        url(r'^admin/', admin.site.urls),
        url(r'^mshow/', include('mshow.urls', namespace='mshow')),
        url(r'^blog/', include('blog.urls', namespace='blog')),
        url(r'^comments/', include('django_comments.urls')),
        url(r'^media/(?P<path>.*)$', 'django.views.static.serve',{'document_root': settings.MEDIA_ROOT}),
        url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},name='django.contrib.sitemaps.views.sitemap'),
    ]

在models里面添加get_absolute_url,凡是需要形成sitemap的类都需要有这个项

    def get_absolute_url(self):
        return "/blog/single/%i/" % self.id

完成之后访问sitemap.xml就可以访问网站的sitemap了,后面还有一些其他功能等待补充。

2016/6/26 posted in  python

django 生产环境 nginx+uwsgi环境安装

django 生产环境

django部署生产环境使用的比较多的是nginx+uwsgi和 apache+mod_python

由于对nginx比较熟一些,所以这里先使用nginx来进行部署。

安装pip

    $ sudo apt-get install python-pip python-dev build-essential 
    $ sudo pip install --upgrade pip 
    $ sudo pip install --upgrade virtualenv 

安装uwsgi

将nginx作为服务器最前端,它将接收WEB的所有请求,统一管理请求。nginx把所有静态请求自己来处理(这是NGINX的强项)。然后,NGINX将所有非静态请求通过uwsgi传递给Django,由Django来进行处理,从而完成一次WEB请求。

第一步先解决uwsgi与django的桥接。解决在没有nginx的情况下,如何使用uwsgi+DJANGO来实现一个简单的WEB服务器。

第二步解决uwsgi与Nginx的桥接。通过nginx与uwsgi的桥接,打通nginx与django的连通,从而比较完美的实现django的部署。

安装uwsgi

    $ export LDFLAGS="-Xlinker --no-as-needed"
    $ pip install uwsgi

测试uwsgi
在你的机器上写一个test.py

    #test.py
    def application(env, start_response):
        start_response('200 OK', [('Content-Type','text/html')])
        return "Hello World"

然后执行shell命令:

    uwsgi --http :8001 --wsgi-file test.py

访问网页:

    http://127.0.0.1:8001/

看在网页上是否有Hello World

安装django

django安装,我用的是比较新的版本,由于老版本总是出现这样那样的问题,也和最新的文档对接不上,django的版本升级实在是太快了。

    sudo pip install django==1.9.6

安装git

安装git,来远程获取代码

    sudo apt-get install git

安装好git之后需要导入我的代码,创建一个目录,然后在目录下

    git init
    git clone https://github.com/yourwilliam/melonblog

就可以将代码clone到本地了。

安装pip

使用django还需要把代码依赖的python包考到本地,这里也使用pip来管理,pip的安装和配置参看其他的博客中有介绍。

安装MySQL数据库和相关python驱动包

    sudo apt-get install mysql-server
    apt-get install mysql-client
    sudo apt-get install libmysqlclient-dev
    sudo apt-get install python-mysqldb

创建数据库

需要 create database

使用python来创建数据库

    python manage.py migrate
    # 创建数据库
    python manage.py makemigrations blog
    python manage.py makemigrations mshow
    # 创建各个APP的数据库
    python manage.py migrate

启动django做测试

    python manage.py runserver 0.0.0.0:8001
    root@iZ23b233aiuZ:/home# pip install django-wsgi

配置uwsgi

详细可以参考

五步教你实现使用Nginx+uWSGI+Django方法部署Django程序上

五步教你实现使用Nginx+uWSGI+Django方法部署Django程序下

编写django_wsgi.py文件,将其放在与文件manage.py同一个目录下

编写文件时需要注意语句os.environ.setdefault。比如,如果你的项目为mysite,则你的语句应该是 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

    #!/usr/bin/env python
    # coding: utf-8
    import os
    import sys
    # 将系统的编码设置为UTF8
    reload(sys)
    sys.setdefaultencoding('utf8')
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
    from django.core.wsgi import get_wsgi_application
    application = get_wsgi_application()

升级了django和wsgi新版本之后这里需要改为

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

import os
import sys

# 将系统的编码设置为UTF8
import django

reload(sys)
sys.setdefaultencoding('utf8')

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "hansapwiki.settings")
django.setup()

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

启动

    udo uwsgi --http :8000 --chdir /opt/melonblog/melonblog --module django_wsgi

在这里的时候访问页面,出现css,js或者图片无法加载,可以不用担心,因为此时uwsgi仅仅处理数据请求,这些静态文件需要使用nginx来读取,在配置好nginx之后就可以配置了。

配置uwsgi的XML文件

djangochina_socket.xml, 将这个文件配置为

    <uwsgi>
        <socket>:8077</socket>
        <chdir>/opt/melonblog/melonblog</chdir>
        <module>django_wsgi</module>
        <processes>4</processes> <!-- 进程数 -->
        <daemonize>uwsgi.log</daemonize>
    </uwsgi>        

安装nginx

安装nginx

    sudo apt-get install nginx
    #启动、停止和重启
    sudo /etc/init.d/nginx start
    sudo /etc/init.d/nginx stop
    sudo /etc/init.d/nginx restart
    #或者
    sudo service nginx start

配置nginx

使用apt-get获取的nginx默认的在_etc_nginx/ 下,修改下面的nginx.conf 文件

server {
    
    listen   80;
    server_name 121.41.8.92;
    access_log /var/log/nginx/melonblog/access.log;
    error_log /var/log/nginx/melonblog/error.log;
    
    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
     include        uwsgi_params;
     uwsgi_pass     127.0.0.1:8077;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    location /static/ {
        alias  /opt/melonblog/melonblog/blog/static/;
        index  index.html index.htm;
    }

    location /media/ {
        alias  /opt/melonblog/melonblog/blog/static/media/;
    }
}

这样便设置了上面的目录结构

配置完成后重启nginx nginx -s reload

启动uwsgi服务器

    cd /opt/melonblog/melonblog/
    uwsgi -x djangochina_socket.xml

关闭uwsgi进程的方法

    ps -ef|grep uwsgi 
    #如果启动没有完成,这个是没有进程的,有进程代表启动成功
    kill -9 *****
    #将所有的进程杀死可以完成

其他配置

admin的样式问题

由于后台使用admin 模块,在django服务器中,会默认的将所有的static文件都写入到static目录中。但是此时是由nginx来进行静态文件转发,所以无法转发,需要在转发中添加admin部分的静态文件,在nginx配置文件中添加

    location /static/admin/ {
                alias /usr/local/lib/python2.7/dist-packages/django/contrib/admin/static/admin/;
            }
2016/6/21 posted in  python

django 为生产环境部署的改进点

django 为生产环境部署的改进点

django在生产环境部署的时候,支持多种部署方式,由于对Nginx比较熟,当前采用的是nginx+uwsgi的方式进行部署。配置完成之后,发现一些问题可能和之前的代码也有相应的关系,需要对代码进行重构和优化,以适应生产部署环境。在这里做一个总结。

static文件

在django的生产环境中,如果使用nginx+uwsgi,这时主要的请求是从uwsig来提供,然后在到nginx。而静态文件则直接通过nginx来访问。所以我们会在nginx里面配置相关的参数来指定nginx 的static目录从哪里走。

但是区别是在django容器中,在每个APP中部署的static文件夹,为默认的集中到同一个static目录中,形成统一的static路径。而nginx主要使用alias来解决单一的路径,这时某些路径可能就被丢掉了。造成部分文件无法访问。对于这种情况,我采用的解决方法是在源文件中将所有的static文件提取到根目录,这样所有的app都可以访问该目录,同时在生产环境时,只需要将nginx指定到这个目录就可以了。

看了一下源代码,不知道这是不是也是大多数工程会被static文件丢到外面来的原因。

static最佳实践

仔细研究了一下static的形成方式,以及相关整理方式,整理了一下static的相关实践方式

static的几个配置的研究

staticfiles的主要相关配置与分析

STATIC_ROOT:运行命令python manage.py collectstatic 之后静态文件将要复制到的目录,这个目录只有在运行collectstatic时候才会用到,不能想当然的以为这个目录和MEDIA_ROOT的作用是相同的,否则在开发环境的时候可能一直无法找到静态文件。

STATIC_URL:设置的static file的起始url,这个只是在template里边引用到,这个参数和MEDIA_URL的含义相同。

STATICFILES_DIRS:和TEMPLATE_DIRS的含义差不多,就是除了各个app的static目录以外还需要管理的静态文件设置,比如项目的公共文件差不多。

这几个项比较清楚了,下面仔细的分析一下python manage.py collectstatic这个命令

collectstatic命令

我们刚才上面有研究一下static文件,由于static文件是散落到各个部分的,我们不容易管理。而且从其他包引入的app,其静态文件还可能在site-package文件目录中,这样导致了文件上线后非常不好维护。

所以有了collectstatic命令,这个命令将所有的静态文件统一的手机到STATIC_ROOT目录所定义的位置,这样就不会在生产部署,如nginx下,需要alias的时候导入一大堆的包了,只需要导入这一个路径便能管理所有的静态文件。

讲一下static和media的区别

static更多的是存放如网页相关 css\javascript\image等文件。

media更多的存放运行时导入的图片、文档等动态文件。

讲讲最佳实践

所以在有collectstatic这个命令之后,我们不需要讲静态文件全部放在一个目录下,static文件还是在每个app中管理,这样对于app级别更加清晰,然后在每次需要发包的时候执行 python manage.py collectstatic就可以将所有的文件都导出到static路径下,这样线上的nginx可以直接使用配置这个路径到static中就可以了。

开发环境和线上环境:

在开发环境上,我们需要不时的修改static文件来满足我们的修改需要,此时如果试用static文件的话,那么每次修改必须要重新collectstatic才能重新发布静态文件。因为静态文件会首先使用static文件夹里面的静态文件来发布。所以不建议在开发环境上做collectstatic来进行static文件的收集。而是到正式环境中后,把所有的静态文件统一收集到这里。这样方便生产环境做静态文件配置化。

问题

发现如果在本地开发库里面就将static导入,运行collectstatic的话,会生成2份静态static文件,对于CSS等路径,在员路径修改就不生效了,会对开发造成一定的麻烦,所以最好还是在开发路径中不适用collectstatic,然后在正式发布环境上进行全路径的collectstatic,这样会更有效。

2016/6/21 posted in  python