mac上安装python3 的两种环境配置方法和分析

mac上一般可以使用homebrew来管理多个版本的python,现在python的两个版本分化的比较明显,所以现在实际上两个版本一般都在使用。

使用homebrew来安装python之后python一般都会安装在

williamtekiMacBook-Pro:~ valentine$ which python3
/usr/local/Cellar/python/3.6.4_2/bin//python3

在Cellar目录下,如果在不加配置的时候使用python的话,需要到这个目录,这个实在有点复杂。

配置执行目录有两种方法,一种是将这个目录添加到PATH中去,另外一种是修改系统的执行目录。

方法一:

修改 ~/.bash_profile文件,系统每次在启动的时候都会调用这个文件来初始化环境变量,所以可以直接在里面添加

export PATH=/usr/local/Cellar/python/3.6.4_2/bin/:${PATH}

不用担心,其他的环境变量一般也会配置在这个地方

方法二:

修改系统的可执行环境目录,/etc/paths
并且修改其中的相应环境变量顺序。

2018/12/15 posted in  python

redux 知识整理

redux文档

基础知识

基本思想

State,记录应用的状态。
Action,记录对应用的动作,描述发生了什么
reducer,reducer接收state和action,并返回新的state函数。

核心概念

state : 普通对象,类似一个json串,或者类似Model,存储当前的数据状态

{
  todos: [{
    text: 'Eat food',
    completed: true
  }, {
    text: 'Exercise',
    completed: false
  }],
  visibilityFilter: 'SHOW_COMPLETED'
}

action: 要像更新state中的数据,需要发起一个action。action就像是描述发生了什么的指示器。

{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }

reducer: reducer只是一个接收state和action,并返回新的state的函数。对于大的应用来说,不大可能仅仅只写一个这样的函数,所以我们编写很多小函数来分别管理 state 的一部分。

function visibilityFilter(state = 'SHOW_ALL', action) {
  if (action.type === 'SET_VISIBILITY_FILTER') {  //这里的判断为当为指定类型的action的时候,处理特定方法来返回state
    return action.filter;
  } else {
    return state;
  }
}

function todos(state = [], action) {
  switch (action.type) {
  case 'ADD_TODO':
    return state.concat([{ text: action.text, completed: false }]); //给state增加内容
  case 'TOGGLE_TODO':
    return state.map((todo, index) =>
      action.index === index ?
        { text: todo.text, completed: !todo.completed } :
        todo
   )
  default:
    return state;
  }
}

三大原则

  1. 整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
  2. State 是只读的,唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
  3. 使用纯函数来执行修改,刚开始你可以只有一个 reducer,随着应用变大,你可以把它拆成多个小的 reducers,分别独立地操作 state tree 的不同部分

基础

Action

  1. Action 是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store。
  2. Action 本质上是 JavaScript 普通对象。我们约定,action 内必须使用一个字符串类型的 type 字段来表示将要执行的动作。多数情况下,type 会被定义成字符串常量。当应用规模越来越大时,建议使用单独的模块或文件来存放 action。
  3. Redux 中只需把 action 创建函数的结果传给 dispatch() 方法即可发起一次 dispatch 过程

Reducer

  1. Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。
  2. 现在我们已经确定了 state 对象的结构,就可以开始开发 reducer。reducer 就是一个纯函数,接收旧的 state 和 action,返回新的 state。
  3. 在高级篇里会介绍如何执行有副作用的操作。现在只需要谨记 reducer 一定要保持纯净。只要传入参数相同,返回计算得到的下一个 state 就一定相同。没有特殊情况、没有副作用,没有 API 请求、没有变量修改,单纯执行计算。

Store

Store 就是把它们联系到一起的对象。Store 有以下职责:

维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。
再次强调一下 Redux 应用只有一个单一的 store。当需要拆分数据处理逻辑时,你应该使用 reducer 组合 而不是创建多个 store。

数据流

  1. 调用 store.dispatch(action)

Action 就是一个描述“发生了什么”的普通对象。比如:


 { type: 'LIKE_ARTICLE', articleId: 42 }
 { type: 'FETCH_USER_SUCCESS', response: { id: 3, name: 'Mary' } }
 { type: 'ADD_TODO', text: 'Read the Redux docs.' }
  1. Redux store 调用传入的 reducer 函数。

Store 会把两个参数传入 reducer: 当前的 state 树和 action。例如,在这个 todo 应用中,根 reducer 可能接收这样的数据:

 // 当前应用的 state(todos 列表和选中的过滤器)
 let previousState = {
   visibleTodoFilter: 'SHOW_ALL',
   todos: [
     {
       text: 'Read the docs.',
       complete: false
     }
   ]
 }

 // 将要执行的 action(添加一个 todo)
 let action = {
   type: 'ADD_TODO',
   text: 'Understand the flow.'
 }

 // reducer 返回处理后的应用状态
 let nextState = todoApp(previousState, action)
  1. 根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树。

  2. Redux store 保存了根 reducer 返回的完整 state 树。

2018/12/6 posted in  web

Gank代码分析

主要分析js中的代码

  1. actions 存储所有的actions行为
    1. actionTypes.js action类型的常量定义,全局action常量
    2. handleCollectionData.js action的具体定义
    3. modifySettings.js
    4. requestCategoryData.js 调用接口获取目录数据
    5. requestHomeData.js 调用接口获取主页数据
    6. requestRandomData.js
  2. assets 图片放在这里
  3. components 定义公用的页面组件
    1. Avatar.js 所有的图标都走这个文件,后面使用,在其他页面引用使用
    2. BackPageComponent.js
    3. ListViewFooter.js 定义
      标签
    4. ListViewForCategory.js
    5. ListViewForCollection.js 定义标签,在首页使用
    6. ListViewForGirls.js
    7. ListViewForHome.js
    8. NavigationBar.js
    9. RowItemWithSwitcher.js
    10. SimpleRowItem.js
  4. constants 定义常量,颜色常量、后台绑定数据常量等
    1. colors.js 定义不同的颜色主题,在APP选择主题的地方可以选择
    2. fetchUrl.js 定义和后台数据绑定的url 这个使用的接口方式是直接get访问,不带任何token类型的,也不鉴权,后面这一块需要加上。
    3. theme.js 定义主题的颜色
  5. containers 定义各个页面的展示内容
    1. CollectionTab 收藏页面
    2. DiscoveryTab 发现页面
      1. GirlsPage.js 福利页面
      2. index.js 发现的首页
      3. TextListPage.js 前端数据页面
      4. VideoTabPage.js 休息视频页面
    3. HomeTab 主页
      1. index.js 主页
    4. MoreTab 更多的页面信息
      1. AboutAuthorPage.js 关于作者页面
      2. AboutGankPage.js 关于Gank
      3. index.js 更多页面配置
      4. OrderContentPage.js
      5. ThemeColorPage.js 主题颜色页面
    5. MainPage.js
    6. WebViewPage.js
  6. dao 存储数据,这个使用的存储是放在AsyncStorage中的,不同的数据指定不同的key存储
    1. FavouriteDataDAO.js
    2. HomeDataDAO.js
    3. RandomDataDAO.js
    4. SettingDataDAO.js
  7. native_modules
  8. reducers 定义不同的reducers
    1. categoryDataState.js
    2. favorDataState.js
    3. homeDataState.js
    4. index.js
    5. randomDataState.js
    6. settingState.js
  9. store 定义store
    1. index.js 使用中间件定义store
  10. utils
    1. fetchWithTimeout.js 设置读取超时时间
    2. getData.js 获取时间的工具
    3. handleHomeDataSource.js 获取目标页面的datasource (从这里可以看出来,所有的datasource是写在results的子集下面的)
    4. imageFactory.js 图片圆角工具
    5. px2dp.js px像素转化dp的工具
    6. shareUtil.js 分享工具
  11. App.js
2018/12/5 posted in  web

ReactNative IOS 指定版本运行

可以使用xcrun来运行查看具体的版本

williamtekiMacBook-Pro:react-native-Gank valentine$ xcrun simctl list devices
== Devices ==
-- iOS 12.1 --
    iPhone 5s (6199ADBB-CB0E-4CDB-8950-A871F1DA9CF0) (Shutdown)
    iPhone 6 (00AB9AE8-E128-4C10-9D62-570250772E8D) (Booted)
    iPhone 6 Plus (E69D1237-B032-4AEF-A813-74637DCBBB39) (Shutdown)
    iPhone 6s (26894AEF-9D10-40CC-B137-293C0252A6F5) (Shutdown)
    iPhone 6s Plus (7A137B77-3E03-473C-B2EE-F2721CD599E7) (Shutdown)
    iPhone 7 (308F8F53-7C35-44F3-9749-D1A27EB83F0D) (Shutdown)
    iPhone 7 Plus (781E31F0-5ABD-472A-BEEE-4184FD41FE67) (Shutdown)
    iPhone 8 (2994B9EF-2EF3-4907-B0BC-A3BA1237CC98) (Shutdown)
    iPhone 8 Plus (F4C073DC-32AB-40E9-8E3B-7390C29697AD) (Shutdown)
    iPhone SE (A95F1C9A-A574-4D87-8BCF-E8F772A01E63) (Shutdown)
    iPhone X (6394A4CF-E2DD-42D1-BAA7-A750EC6FFD7F) (Shutdown)
    iPhone XS (ED451917-64D1-450C-8BF7-FACE896A9985) (Shutdown)
    iPhone XS Max (CEA9C873-9B8B-4153-8095-5F0BEDE8AACE) (Shutdown)
    iPhone XR (38156FC2-A003-4764-A290-AC122F356BB1) (Shutdown)
    iPad Air (E6ADEDFF-C380-40CF-B39E-1A18C421C169) (Shutdown)
    iPad Air 2 (CA3F1EF9-B5D8-402D-97E0-497B15D30E1F) (Shutdown)
    iPad (5th generation) (3459FC77-D370-4082-81AD-2EF8A93D0E03) (Shutdown)
    iPad Pro (9.7-inch) (5ED82ADE-A8CF-4111-9F41-79350B2279BB) (Shutdown)
    iPad Pro (12.9-inch) (DF32A188-7A36-44D8-A3FD-2876A121CB10) (Shutdown)
    iPad Pro (12.9-inch) (2nd generation) (18B3B724-D907-4A04-AF8E-DD8BD15FBA6D) (Shutdown)
    iPad Pro (10.5-inch) (FD76F0D2-3D7A-4827-9319-B910CF8EA4BF) (Shutdown)
    iPad (6th generation) (4AD10639-51B2-407C-8F1E-0C90A6A6EFFC) (Shutdown)
    iPad Pro (11-inch) (23301F25-2B2D-40F2-8FCC-DAB30A2CDD47) (Shutdown)
    iPad Pro (12.9-inch) (3rd generation) (44A5B520-2930-48CB-9D2F-10F7FC74713E) (Shutdown)
-- tvOS 12.1 --
    Apple TV (C93717D7-B1B8-4116-AE7D-4C7A1DF6FBE7) (Shutdown)
    Apple TV 4K (0F4E46DF-35F3-423B-BDD8-4452C5A12D5C) (Shutdown)
    Apple TV 4K (at 1080p) (2C847CB7-5122-4330-BA7A-69ABA7D607F2) (Shutdown)
-- watchOS 5.1 --
    Apple Watch Series 2 - 38mm (CC6C55FE-D942-4DCF-BB9D-3775CB9851D3) (Shutdown)
    Apple Watch Series 2 - 42mm (36C5051E-69D0-47CB-A026-8C54554993A9) (Shutdown)
    Apple Watch Series 3 - 38mm (7DC891D9-A549-4E57-9249-CFE4EA805A20) (Shutdown)
    Apple Watch Series 3 - 42mm (BA5680EA-BDBA-472A-8D71-DE4974CAEDBF) (Shutdown)
    Apple Watch Series 4 - 40mm (7345AF43-04DC-45AD-9CF0-D40A1CF59BF4) (Shutdown)
    Apple Watch Series 4 - 44mm (4F1DC43F-F85E-4CA8-83E9-7A8C43A028CD) (Shutdown)

方法与android 相同,但是有个小问题
Debug 时会调用 react-native run ios命令,而这个命令默认会拉起iPhone 6的模拟器。并且系统版本还会选择现有的较低版本。有时候程序会直接因为版本太低无法运行。
只时候我们可以改一下这个命令的默认配置。
打开porject/node_modules/react-native/local-cli/runIOS/runIOS.js
在module.export 中找到options ,修改其中的Default为别的机型,比如iPhoneX,再次运行就可以默认使用iPhoneX机型Debug了
{
command: '--simulator [string]',
description: 'Explicitly set simulator to use',
default: 'iPhone X',
},

注意使用React Native Tools 进行Debug的时候,先要关闭网页的Debug。否则会提示
Could not debug. Another debugger is already connected to packager. Please close it before trying to debug with VSCode.
这时候,在行内打印断点,可以在下面的控制台查看变量进行调试,也可以用最上面的菜单栏控制Debug的步揍

参考文章:

React Native使用VSCode 进行 Debug

2018/12/5 posted in  web

ReactNative Android 真机调试

本篇主要是解决在mac下配置ReactNative Android下面的真机调试配置

ReactNative

1. 安装Android SDK Manager

下载地址

下载完成后进入tools目录下执行./android sdk,打开Manager界面

首先把一些必须要安装的SDK安装了

  1. Android SDK Tools
  2. Android SDK Platform-tools
  3. Android SDK Build-tools
  4. Android 8.0.0下的SDK-Platform 这个可以根据具体要发布的版本来进行安装
  5. Extra下的Android Support Repository

这几个是必须安装的,否则打包的时候会报错

2. 配置环境变量

最好的方式是配置环境变量到touch ~/.bash_profile里面,我由于硬盘不够,装在U盘上,如果写在里面加载的时候可能会出现问题,所以每次需要使用的时候手动加载一下环境变量吧

/**
网上很多地方写的Android SDK的位置在/Users/xxxx/Library/Android/sdk 目录下,这个是在手动安装了Android Studio之后才会有的,我们这里没有安装Android Studio,所以没有这个配置文件。配置Android Home是直接写到android-sdk-manager-macosx的目录下。
*/
export PATH=${PATH}:/Volumes/UDisk32G/android-sdk-manager-macosx/platform-tools/
export PATH=${PATH}:/Volumes/UDisk32G/android-sdk-manager-macosx/tools/
export ANDROID_HOME=/Volumes/UDisk32G/android-sdk-manager-macosx/ 
//

export PATH=${PATH}:/Volumes/WD1TExtensi/tools/android-sdk-macosx/platform-tools/
export PATH=${PATH}:/Volumes/WD1TExtensi/tools/android-sdk-macosx/tools/
export ANDROID_HOME=/Volumes/WD1TExtensi/tools/android-sdk-macosx/ 

配置完成后可以使用adb version来查看一下是否安装成功

3. 连接设备

手上测试的是一台小米Mix,小米的手机需要配置几个地方

  1. 连接上去之后USB选项配置“传输文件”
  2. 设置开发者模式,设置——我的设备——全部参数——MIUI版本(多次点击就可以开启)
  3. 设置开发者选项,设置——更多设置——开发者选项。打开USB调试、USB安装。关闭启用MIUI优化。

查看设备信息

system_profiler SPUSBDataType

创建adb_usb.ini文件,在文件中添加0x2717后保存退出

$ vi ~/.android/adb_usb.ini

重启adb

$ adb kill-server

$ adb start-server

$ adb devices

最后在devices里面可以看到设备连接表,如果这里返回空的说明配置有问题

到目录下运行程序

$ react-native run-android

遇到的问题

1. Could not determine java version from '10.0.1'[MAC OSX High Sierra]

这个是由于Java版本太新,而Gradle版本太老大致的

解决:首先 homebrew upgrade gradle 来更新mac上的版本,然后在修改配置

修改依赖的gradle版本 android/gradle/wrapper/gradle-wrapper.properties

#Wed Nov 23 12:42:37 AEDT 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.0-all.zip     //这里使用5.0版本是应为使用homebrew upgrade gradle之后update到的是gradle-5.0版本,保持同步

在代码文件的android/build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {  
    repositories {
        google()    //注意这个地方需要加上,否则会报错
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'   //这里的版本号需要和gradle文件的配置版本号匹配,否则无法加载。和上面的gradle-5.0匹配的是3.2.1版本,这个可以在官网上查到

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()   //注意这个地方需要加上,否则会报错
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
}

gradle版本对应可以参考下图

具体参考了这几篇文章

ReactNative Mac配置安卓真机调试环境

添加google()配置

官网的Android SDK配置路径

在MacOSX中安装Android SDK

整理部分依赖不存在,需要安装extra中的Android Support Repository插件

2018/12/5 posted in  web

ReactNative入门

tutorial
https://reactnative.cn/docs/tutorial/

脚手架之一

基于react-native+redux搭建的P2P开源App
https://github.com/seawind8888/react-native-P2P

整理好了基本使用之后多了解几个脚手架,使用一个脚手架开始开发。

ECS6规范

查看运行的8081端口是否开启,如果开启了会报各种莫名的错误

lsof -n -i4TCP:8081
2018/12/3 posted in  web

uwsgi的ini配置方法

在前面的文章使用xml的方式配置的uwsgi容器,但是xml方式可以配置的参数较少,而且配置比较老,现在修改成为使用ini方式配置

配置文件如下:

[uwsgi]
chdir = /opt/destiny/destiny-core
home = /opt/destiny/destinyenv
module = destiny.wsgi:application
#wsgi-file = /opt/destiny/destiny-core/django_uwsgi.py

master = true
processes = 2
enable-threads = true

# use unix socket because it is more secure and faster than TCP socket
socket = %(chdir)/uwsgi/uwsgi-destiny.sock
status = %(chdir)/uwsgi/uwsgi-destiny.status
pidfile = %(chdir)/uwsgi/uwsgi-destiny.pid
daemonize = %(chdir)/uwsgi/uwsgi.log


chmod-socket = 662
vacuum = true
die-on-term = true

logto = %(chdir)/uwsgi/uwsgi-destiny.log

env = LANG=en_US.UTF-8
env = LC_ALL=en_US.UTF-8
env = PYTHONIOENCODING=UTF-8

# 如果不加最后两行会报错 UnicodeEncodeError: 'ascii' codec can't encode character

nginx配置如下

server {
    listen   80;
    listen   443 ssl;
    charset utf-8;
    server_name  destiny.wonderfultop.com;
    access_log  /var/log/nginx/destiny/access.log;
    error_log   /var/log/nginx/destiny/error.log;

    proxy_http_version 1.1;
    proxy_set_header Connection "";

    ssl on;
    ssl_certificate /opt/destiny/config/Nginx/*.crt;
    ssl_certificate_key /opt/destiny/config/Nginx/*.key;

    location / {

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        include uwsgi_params;
        uwsgi_pass_request_body on;
        uwsgi_pass_request_headers on;
        uwsgi_pass  unix:/opt/destiny/destiny-core/uwsgi/uwsgi-destiny.sock;
        uwsgi_read_timeout 1800;
        uwsgi_send_timeout 300;
        proxy_connect_timeout 600;
        proxy_read_timeout 600;
        sendfile        on;
        client_max_body_size 20M;
        keepalive_timeout  0;
    }


    location /static/ {
        alias /opt/destiny/destiny-core/static/;
    }
}
#启动

uwsgi --ini uwsgi_destiny.ini

#退出
kill
2018/11/22 posted in  python

图片素材网站运作模式和问题分析

unsplash

  1. unsplash api集成到各个平台 https://medium.com/unsplash/refresh-your-website-with-squarespace-unsplash-15b1b69c2f5b?vero_id=252265&vero_conv=PmNPLiUVlfrNjJJhv63oChcuLeUlQmG8XzCeThlHmBIC7swdfqiZKMCfDL2hUMpzzsQ8AxKplzpI8LiWCWXEbA2LKMZtQGJm

千图的问题

http://www.p5w.net/news/tech/201612/t20161207_1657118.htm

转知乎图片素材下载网站盈利模式

作者:挥霍123
链接:https://www.zhihu.com/question/63401799/answer/209494166
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你好,就拿PPT网站来举例,如果觉得回答得满意,别忘了点赞或者关注哟第一种类型网站:免费素材下载网站(51PPT模板网站、51PPT、无忧PPT),像这样的网站,提供许多免费的PPT模板供我们下载,但是却在网站植入了许多广告,利用广告点击率赚钱第二种类型网站:大部分作品需要付费下载的网站(演界网、PPTSTORE、稻壳儿网),这些网站的PPT模板质量相对于其他平台较高,网站基本上靠顾客下载模板赚钱,当作品的作品被许多人下载后,提现时,一般平台会收取30%左右的平台费,基本上是靠这个费用来赚钱的。第三种类型网站:普通用户每天只能下载3次左右,VIP可以下载20左右,当然还要看你冲的什么VIP,不同的VIP享受不同的特权,这种网站我把他叫做会员制网站(千图网、摄图网、我图网)这些网站之所以可以免费下载,是因为大部分的作品都是从别的平台上搬运过来的,比如千图网,PPT模板50%都是从别的平台上原封不动的搬运过来的,我曾经在演界网免费分享过一份高质量的PPT模板,也被千图网原封不动的盗版了。我国最顶端的平台的作品几乎都千图网盗版过,之所以会有这样的网站的出现,是因为中国对版权法的不够重视,还有创办网站的人在打擦边球,还有一个重要的原因就是互联网共享资源的快速发展。那这些会员制网站是靠什么赚钱呢?其一,因为资源是免费的,质量较好,靠流量下载赚钱其二,因为普通用户下载数量会有限制,会员又比较便宜,所以很多人选择了开会员那么这么庞大且质量较高的资源到底是如何来到?显而易见,这些资源大部分绝非是原创作者发表的,而是其他用户通过盗版直接发表在这些会员制网站上。(这些盗版者的工资据说有两种结算方式:第一种是20块钱一个模板,这么廉价的成本当然可以让网站会员免费下载咯、第二种是通过下载量得到分成,比如说一份模板1角钱,所以还是很多人下载作品的)好了,我也是一个PPT原创作者,也在演界网和稻壳儿上发表自己的作品,里面很多设计师的作品都被千图网盗版者盗版过。最后说两句,版权很重要,会员制的网站的作品千万别商用,因为版权很难得到保证。珍重原创,拒绝盗版

2018/11/22 posted in  随心记

有意思的linux下开发

#直接查找当前文件夹中有某字段的文件
(redashenv) root@yourwilliam-ubuntu:/home/yourwilliam/workspace/redash/redash/client/app# grep -rn dashboard-widget-wrapper
pages/dashboards/public-dashboard-page.html:11:      <div class="dashboard-widget-wrapper"
pages/dashboards/dashboard.less:38:  .dashboard-widget-wrapper:not(.widget-auto-height-enabled) {
pages/dashboards/dashboard.html:94:      <div class="dashboard-widget-wrapper"

引用说明

Linux查找含有某字符串的所有文件

  • : 表示当前目录所有文件,也可以是某个文件名

-r 是递归查找

-n 是显示行号

-R 查找所有文件包含子目录

-i 忽略大小写

下面是一些有意思的命令行参数:

grep -i pattern files :不区分大小写地搜索。默认情况区分大小写,

grep -l pattern files :只列出匹配的文件名,

grep -L pattern files :列出不匹配的文件名,

grep -w pattern files :只匹配整个单词,而不是字符串的一部分(如匹配‘magic’,而不是‘magical’),

grep -C number pattern files :匹配的上下文分别显示[number]行,

grep pattern1 | pattern2 files :显示匹配 pattern1 或 pattern2 的行,

grep pattern1 files | grep pattern2 :显示既匹配 pattern1 又匹配 pattern2 的行。

这里还有些用于搜索的特殊符号:

< 和 > 分别标注单词的开始与结尾。

例如:

grep man * 会匹配 ‘Batman’、‘manic’、‘man’等,

grep '<man' * 匹配‘manic’和‘man’,但不是‘Batman’,

grep '<man>' 只匹配‘man’,而不是‘Batman’或‘manic’等其他的字符串。

'':指匹配的字符串在行首,

'$':指匹配的字符串在行尾,

2018/11/18 posted in  linux

redash dashboard修改指南

# dashboard展示页面在这里
redash/redash/client/app# vi pages/dashboards/dashboard.html

# 修改dashboard中放置图形化内容的区域
/home/yourwilliam/workspace/redash/redash/client/app# vi components/dashboards/widget.html


2018/11/18 posted in  python

redash 前台开发指南

前台开发指南

redash 开发中需要起三个进程,webserver、celery和webpack ,三个的启动方式如下

#Web server: 
bin/run ./manage.py runservrer --debugger --reload
#Celery: 
./bin/run celery worker --app=redash.worker --beat -Qscheduled_queries,queries,celery -c2
#Webpack dev server: 
npm run start

前台开发直接修改webpeck即可,启动不使用npm run start,而是使用npm run watch

相应的开发内容在前面的文档里面已经整理过了

发布方式

当前没有使用docker开发模式,而是使用本地安装后开发,开发之后上传到git,然后再在生产环境docker上面进行发布

dashboard黑色主题修改

修改路径:

  1. 研究出来具体的修改点,在dashboard修改点配置完成
  2. 将修改点析出,改为配置化

修改路径

  • 修改dashboard的背景
    root@yourwilliam-ubuntu:/home/yourwilliam/workspace/redash/redash/client/app# vi pages/dashboards/dashboard.html

添加bg-black

  • 修改具体的widget的background

root@yourwilliam-ubuntu:/home/yourwilliam/workspace/redash/redash/client/app# vi components/dashboards/widget.html

添加bg-black

  • 修改具体的图表的背景透明

修改处

root@yourwilliam-ubuntu:/home/yourwilliam/workspace/redash/redash/client/app# vi visualizations/chart/plotly/utils.js

  • 修改顶部的头背景

root@yourwilliam-ubuntu:/home/yourwilliam/workspace/redash/redash/client/app# vi pages/dashboards/dashboard.html

2018/11/17 posted in  python

ubuntu配置postgres远程连接

修改远程连接属性

  1. 修改postgresql.conf

postgresql.conf存放位置在/etc/postgresql/9.x/main下,这里的x取决于你安装PostgreSQL的版本号,编辑或添加下面一行,使PostgreSQL可以接受来自任意IP的连接请求。

listen_addresses = '*'

  1. 修改pg_hba.conf

pg_hba.conf,位置与postgresql.conf相同,虽然上面配置允许任意地址连接PostgreSQL,但是这在pg中还不够,我们还需在pg_hba.conf中配置服务端允许的认证方式。任意编辑器打开该文件,编辑或添加下面一行。

#TYPE  DATABASE  USER  CIDR-ADDRESS  METHOD
host  all  all 0.0.0.0/0 md5

默认pg只允许本机通过密码认证登录,修改为上面内容后即可以对任意IP访问进行密码验证。对照上面的注释可以很容易搞明白每列的含义,具体的支持项可以查阅文末参考引用。

完成上两项配置后执行sudo service postgresql restart重启PostgreSQL服务后,允许外网访问的配置就算生效了。

配置默认用户密码

设置PostgreSQL的用户名和密码
因为PostgreSQL在安装初始化后就会存在一个账户 postgres ,可以称之为叫做超管的账户,我们现在需要做的是修改这个账号的密码。

sudo su # 切换到 root 账号
su - postgres # 切换到 postgres 账号
psql # 进入 postgresql 工作台
alter user postgres with password '你的密码'; # 执行此命令修改成你的密码
\q # 退出工作台

navicat 配置

navicat 配置postgresql数据库连接

2018/11/14 posted in  linux

ubuntu 18 vnc 连接

2018/11/14 posted in  linux

Redash 安装脚本

REDASH_BASE_PATH=/opt/redash

install_docker(){
    # Install Docker
    sudo apt-get update
    sudo apt-get -yy install apt-transport-https ca-certificates curl software-properties-common wget pwgen
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
    sudo apt-get update && sudo apt-get -y install docker-ce

    # Install Docker Compose
    sudo curl -L https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
    sudo chmod +x /usr/local/bin/docker-compose

    # Allow current user to run Docker commands
    sudo usermod -aG docker $USER
}

第一句把base目录配置死了配置到/opt/redash目录,如果要改目录不是改这里就可以了的,下面别的地方也写死了一些目录的结构。

第一部分主要是安装docker容器,并安装docker-compose编排组件。

create_directories() {
    if [[ ! -e $REDASH_BASE_PATH ]]; then
        sudo mkdir -p $REDASH_BASE_PATH
        sudo chown $USER:$USER $REDASH_BASE_PATH
    fi

    if [[ ! -e $REDASH_BASE_PATH/postgres-data ]]; then
        mkdir $REDASH_BASE_PATH/postgres-data
    fi
}

创建/opt/redash/和/opt/redash/postgres-data目录

create_config() {
    if [[ -e $REDASH_BASE_PATH/env ]]; then
        rm $REDASH_BASE_PATH/env
        touch $REDASH_BASE_PATH/env
    fi

    COOKIE_SECRET=$(pwgen -1s 32)
    POSTGRES_PASSWORD=$(pwgen -1s 32)
    REDASH_DATABASE_URL="postgresql://postgres:${POSTGRES_PASSWORD}@postgres/postgres"

    echo "PYTHONUNBUFFERED=0" >> $REDASH_BASE_PATH/env
    echo "REDASH_LOG_LEVEL=INFO" >> $REDASH_BASE_PATH/env
    echo "REDASH_REDIS_URL=redis://redis:6379/0" >> $REDASH_BASE_PATH/env
    echo "POSTGRES_PASSWORD=$POSTGRES_PASSWORD" >> $REDASH_BASE_PATH/env
    echo "REDASH_COOKIE_SECRET=$COOKIE_SECRET" >> $REDASH_BASE_PATH/env
    echo "REDASH_DATABASE_URL=$REDASH_DATABASE_URL" >> $REDASH_BASE_PATH/env
}

配置ENV文件,把这几个相关数据都写入env配置文件中

setup_compose() {
    REQUESTED_CHANNEL=stable
    LATEST_VERSION=`curl -s "https://version.redash.io/api/releases?channel=$REQUESTED_CHANNEL"  | json_pp  | grep "docker_image" | head -n 1 | awk 'BEGIN{FS=":"}{print $3}' | awk 'BEGIN{FS="\""}{print $1}'`

    cd $REDASH_BASE_PATH
    REDASH_BRANCH="${REDASH_BRANCH:-master}" # Default branch/version to master if not specified in REDASH_BRANCH env var
    wget https://raw.githubusercontent.com/getredash/redash/${REDASH_BRANCH}/setup/docker-compose.yml
    sed -ri "s/image: redash\/redash:([A-Za-z0-9.-]*)/image: redash\/redash:$LATEST_VERSION/" docker-compose.yml
    echo "export COMPOSE_PROJECT_NAME=redash" >> ~/.profile
    echo "export COMPOSE_FILE=/opt/redash/docker-compose.yml" >> ~/.profile
    export COMPOSE_PROJECT_NAME=redash
    export COMPOSE_FILE=/opt/redash/docker-compose.yml
    sudo docker-compose run --rm server create_db
    sudo docker-compose up -d
}

获取网上的redash-compose.py文件,export相应的配置项,同时创建数据库。
使用docker-compose up -d 将所有配置和数据文件同步。

2018/11/14 posted in  python

redash docker deploy

redash官方提供了基于docker下面的deploy文档,在目录setup下面。https://github.com/yourwilliam/redash/tree/master/setup

这份脚本是基于ubuntu18.04的,建议在ubuntu18下面进行安装部署

具体使用步骤如下:

1. 切换apt源

ubuntu18 版本安装完成之后发现里面并没有包含所有的官方源,最好是切换到国内的源,这样速度也更快。

修改/etc/apt/sources.list文件,记得最好把这个文件备份一个,方便后面修复。

中科大源

deb https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.ustc.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse

然后执行命令:

sudo apt-get update
sudo apt-get upgrade

也可以使用其他的源,如下

阿里源

deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse

163源

deb http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.163.com/ubuntu/ bionic-backports main restricted universe multiverse

清华源

deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ bionic-proposed main restricted universe multiverse

git clone 下载

注意脚本里面很多东西都写了绝对目录,默认认为redash在目录 /opt/redash下,所以也是在opt目录下面进行git clone可以指定到对应的路径下。尽量不要自己修改目录,否则要修改的地方会很多。

执行setup/setup.sh文件

执行setup文件就可以安装

docker配置

在docker中检查当前网络状况要使用ping命令的时候,有时候由于没有安装无法使用,这时候可以自己安装

#1. 首先一定要更新源

apt-get update

#2. 安装工具包

apt-get install vim      # 安装vim

 apt-get install  telnet  # 安装telnet 

 apt-get install  net-tools  # 安装ifconfig 

apt install iputils-ping  # 安装ping

通过root进入docker容器

docker exec -i -t -u 0 e575dad3beae /bin/bash
# 其中e575dad3beae 通过docker ps获取

问题

问题1:

直接安装后,会出现一个权限不足的问题,页面无法访问

是由于在docker中执行npm build 和 npm start的时候是使用的redash用户,而不是root用户,所有数据库无法连接,同时很多文件没有权限访问

当前解决办法:

通过docker ps查询所在使用的容器实例,找到实例id。然后通过root进入到docker中执行命令docker exec -i -t -u 0 e575dad3beae /bin/bash,进去之后重新执行upm build 和 npm start即可。

问题2:

使用Nginx解析到5000端口之后无法登陆。

状态是访问 api目录的时候返回502.
返回结果,报错为:
It seems like we encountered an error. Try refreshing this page or contact your administrator.

使用docker-compose up看日志,没有看到系统的错误日志,返回都是200。那么应该是前端的错误。找到Nginx错误日志,返回以下结果:

2018/11/12 18:57:10 [error] 2002#0: *26219243 upstream sent too big header while reading response header from upstream, client: 61.183.143.20, server: bi2.hansap.com, request: "GET /api/organization/status HTTP/1.1", upstream: "http://*.*.*.*:5000/api/organization/status", host: "*******", referrer: "http://*******/"

从这里看那么就可以说明应该是Proxy配置问题,需要添加配置:

server {

        listen       80;
        server_name  **********;

        gzip on;
        gzip_types *;
        gzip_proxied any;

        location / {
            proxy_pass http://***.***.***.***:5000/;
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
            #proxy_pass_request_body on;
            client_max_body_size 100m;
            proxy_redirect off;
            proxy_buffer_size 64k;
            proxy_buffers   32 32k;
            proxy_busy_buffers_size 128k;
        }
    }

完成之后重新load就可以访问了。

问题3 配置邮件

开发环境的配置文件在 /opt/redash/.env 下,正式环境的配置文件在/opt/redash/env下

但是如果是docker安装,docker会默认读取docker的环境变量,所以在/opt/redash/env下的环境变量不会生效(不知道官网怎么这么写,害人啊) 具体的可以参看

官网 https://redash.io/help/open-source/setup 官网的作为参考,按这个配置不能生效

解决问题的帖子 https://discuss.redash.io/t/where-is-opt-redash-env/999

原因是docker的环境变量需要写在docker compose的配置文件内,内部才能读取。所以这里的env 仅仅只是一个参考,修改了也是没有效果的

具体配置如下:

# /opt/redash/docker-compose.yml文件

version: '2'
services:
  server:
    build: .
    command: dev_server
    depends_on:
      - postgres
      - redis
    ports:
      - "5000:5000"
    volumes:
      - ".:/app"
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://redis:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
      REDASH_MAIL_SERVER: "smtp.hansap.com"
      REDASH_MAIL_PORT: 25
      REDASH_MAIL_USE_TLS: "false"
      REDASH_MAIL_USE_SSL: "false"
      REDASH_MAIL_USERNAME: "*****"
      REDASH_MAIL_PASSWORD: "*****"
      REDASH_MAIL_DEFAULT_SENDER: "hansap@hansap.com"
      REDASH_HOST: "http://bi2.hansap.com"
  worker:
    build: .
    command: scheduler
    volumes_from:
      - server
    depends_on:
      - server
    environment:
      PYTHONUNBUFFERED: 0
      REDASH_LOG_LEVEL: "INFO"
      REDASH_REDIS_URL: "redis://redis:6379/0"
      REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
      QUEUES: "queries,scheduled_queries,celery"
      WORKERS_COUNT: 2
      REDASH_MAIL_SERVER: "smtp.hansap.com"
      REDASH_MAIL_PORT: 25
      REDASH_MAIL_USE_TLS: "false"
      REDASH_MAIL_USE_SSL: "false"
      REDASH_MAIL_USERNAME: "******"
      REDASH_MAIL_PASSWORD: "******"
      REDASH_MAIL_DEFAULT_SENDER: "hansap@hansap.com"
      REDASH_HOST: "http://bi2.hansap.com"
      
      ...
2018/11/12 posted in  python