Trade Off

supercalifragilisticexpialidocious

Developing-on-blackberry

Create BlackBerry ID token

here: https://www.blackberry.com/SignedKeys/

If you will develop an app on BlackBerry OS 10 or some new plateform, choose the first checkbox, and you will be requested your BlackBerry ID username and password, other choices I haven’t tried. Then fill a storepass for the key, you can download a file like bbidtoken.csk, save this file to ~/Library/Research In Motion, if you are on Windows or Linux, save this file to where website mentioned.

Create developer certificate file

developer certificate file is a file named author.p12

I have installed a WebWorks SDK, so I can access blackberry tools on /Applications/BB10 WebWorks SDK 2.1.0.13/cordova-blackberry/bin/dependencies/bb-tools/bin, you should change this path as your SDK type, the target file is blackberry-keytool.

blackberry-keytool -genkeypair -storepass <keystore_pw> -author <YOUR_NAME>

This will create the author.p12 file on the same directory described below:~/Library/Research In Mothion

Create debug token

blackberry-debugtokenrequest -storepass <KeystorePassword> -devicepin <YOUR_DEVICE_PIN> ~/Library/Research In Motion/debug_token.bar

This will create debug token bar file on ~/Library/Research In Motion, caution: debug token file must be a *.bar file.

Install debug token on your device

Enable your development mode on your device first (Settings > Security and Privacy > Development Mode)

blackberry-deploy -installDebugToken <path to debug token> -device <DEVICE_IP_ADDRESS> -password <DEVICE_PIN>

Your should get output like these:

1
2
3
4
Info: Sending request: INSTALL_DEBUG_TOKEN
Info: Action: Install Debug Token
Info: File size: 2607
result::success

Then your device development info has changed, “Debug Token Installed”

deploy an hello world to your device

I use WebWorks SDK, so I launched this app on Mac, and fill some info about project on localhost:3123, a web management for development. After created the app, choose “Build” on left hand, fill your device password and keystore password, choose BUILD & INSTALL, you may get output like these:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[INFO]    Target Q10-2b1e42dc selected
[INFO]    Generating debug token
[INFO]    Debug token created.
[INFO]    Deploying debug token to target "Q10-2b1e42dc"
[INFO]    Sending request: INSTALL_DEBUG_TOKEN
[INFO]    Action: Install Debug Token
[INFO]    File size: 2605
[INFO]    result::success
[INFO]    Populating application source
[INFO]    Parsing config.xml
[INFO]    Generating output files
[INFO]    Package created: /Users/dawncold/WebWorks Projects/Project1/platforms/blackberry10/build/simulator/bb10app.bar
[INFO]    Package created: /Users/dawncold/WebWorks Projects/Project1/platforms/blackberry10/build/device/bb10app.bar
[INFO]    BAR packaging complete
[INFO]    Sending request: INSTALL_AND_LAUNCH
[INFO]    Action: Install and Launch
[INFO]    File size: 69497
[INFO]    Installing Project1.testDev_Project1___c8537c58...
[INFO]    Processing 69497 bytes
[INFO]    Progress 100%...
[INFO]    Progress 100%...
[INFO]    actual_dname::Project1.testDev_Project1___c8537c58actual_id::testDev_Project1___c8537c58
[INFO]    actual_version::0.0.1.1result::successLaunching Project1.testDev_Project1___c8537c58...
[INFO]    result::19132657
[INFO]    done

Meanwhile, your app will be opened on your device! webworks launch screen

External Disk With Openwrt

上次笔记本替换下来的硬盘闲在那里很久了,反正闲着没用,不如装点东西,比如监控的图片什么的,每分钟两张的速度拍,一个工作日,大约能有5G的数据,要是都传到七牛那么也就两天,免费的磁盘空间就满了,但绝大多数图片是没意义的,手动删的话,勤快些也行。

不过要是存到磁盘上的话,就无所谓了,500G的空间,怎么能等好几个月之后再考虑,程序员都是很懒很懒的。。。

磁盘是笔记本的2.5英寸STAT接口,需要一根USB2STAT的线,接到已经很疲劳的路由器上(703N改装版),路由器刷了OpenWrt。

登陆路由器后需要装几个软件,一是mount磁盘需要的,二是vsftpd,准备做成ftp供监控使用。把磁盘连接到路由器上而不是直接连到监控上的原因是:假如有人入侵,看到监控一定会破坏,有可能会把磁盘也带走,这样证据就木有了,而连接到路由器上的话,位置比较隐蔽,不容易察觉,会好一些,我就是这么邪恶。。。

对于mount磁盘需要的软件可能是:

1
2
opkg update
opkg install kmod-usb-storage block-mount kmod-fs-ext4

可能不是必须的,但看了文档没怎么研究,反正装了这些能mount了,由于我就一块磁盘,直接mount到了/mnt中。

1
mount /dev/sda1 /mnt

能用后需要把/mnt的owner改为root:root,权限755,在/mnt下创建ftp目录,owner是ftp:ftp,权限755。(ftp用户是装了vsftpd后创建的,所以你需要先装一下vsftpd)

vsftpd的配置:

1
2
3
4
5
6
7
8
9
background=YES
listen=YES
anonymous_enable=NO
chroot_local_user=YES
local_enable=YES
local_root=/mnt
write_enable=YES
local_umask=022
check_shell=NO

研究了一段时间这些配置,第一个建议测试时候用NO,正式开始用就YES,否则会让路由器一直卡在启动vsftpd这里,网路会不可用。比较关键的是local_root,登陆后用户的root目录会在这里,但不能在里面的ftp中,原因和chroot有关,刚刚在/mnt中创建的ftp目录就是ftp用户登陆上去后可操作的地方,所有操作都需要在ftp目录下进行。其他配置具体不详述,具体含义可以看官方的man page,感觉前七行是比较重要的。

ftp搭建过程中出现can not create file和permission方面的问题请检查local_root和里面目录的权限。另外vsftpd有本地用户和匿名用户、虚拟用户等不同的配置,我用的是本地用户的方法,其他两种,除了虚拟用户配置看起来比较麻烦我没有尝试外,匿名用户也配置过,不过后来一直卡在can not create file这里,没再尝试,应该还是权限问题。

下面是OpenWrt启动mount的设置,在/etc/config/fstab中加入:

1
2
3
4
5
6
7
config mount
  option target /mnt
  option device /dev/sda1
  option fstype ext4
  option options rw,sync
  option enabled 1
  option enabled_fsck 0

具体的/mnt和/dev/sda1、ext4根据你的情况做修改,enabled为1就是启动时加载。

没想到的是装了vsftpd,又挂了个磁盘,小路由器还能撑得住,也许还没开始用,等往里写文件的时候再看看。

Role in Postgresql

In PostgreSQL versions before 8.1, users and groups were distinct kinds of entities, but now only role, it is user or group or both.

if you create a role using “CREATE ROLE r1”, r1 is not a user, only a generic role, it is likely a group, you can not find it in pg_user, only in pg_roles table, but if you grant LOGIN privilege to r1, it will be appear in pg_user table.

After installed postgresql cluster, you need execute initdb, and it will create a default role with superuser privilege, costomarily this role(user) named postgres

Role’s attributes: login, superuser, database creation, role creation, initiating replication, password

CREATE USER r1 == CREATE ROLE r1 LOGIN

Tip: It is good practice to create a role that has the CREATEDB and CREATEROLE privileges, but is not a superuser, and then use this role for all routine management of databases and roles. This approach avoids the dangers of operating as a superuser for tasks that do not really require it.

examples:

CREATE ROLE joe LOGIN INHERIT; CREATE ROLE admin NOINHERIT; CREATE ROLE wheel NOINHERIT; GRANT admin TO joe; GRANT wheel TO admin;

joe can access admin privilege by using “SET ROLE admin”, or if joe has the INHERIT, joe can access privilege directly from admin, if joe want to use these privileges, joe must “SET ROLE admin”. Joe can not access privilege from wheel, because admin has the NOINHERIT, admin can not get these privileges, so as joe.

Else Clause in Python Loop

both in while and for loop, if in loop body, no break, no return, no exception is raised, statements in else block will be executed.

1
2
3
4
for x in []:
     print x
else:
     print ‘xxx’

this example will print ‘xxx’, even nothing in list and this loop is not executed.

Iptables -a INPUT -i Eth0 -p Tcp -m Tcp --dport 80 -j ACCEPT

what’s the agreement of -m?

not tcp, it’s “tcp –dport 80”

-m matches, using a somewhat complicated “module matching” mechanism. There are a bunch of pretty cool modules in iptables, for example “recent”.

Iptables MASQUERADE

If you need private hosts communicate with external network, maybe some LXC contaners want to using apt-get, you need add a iptables rule like this:

1
iptables -t nat -A POSTROUTING -s 10.24.1.0/24 ! -d 10.24.1.0/24 -j MASQUERADE

This rule allows network traffic from 10.24.1.x, and destination is not 10.24.1.x, maybe it wants to communicating with 10.24.2.x, but that doesn’t cover in this post, we assumed it want to communicating with Google, the host has an external ip like 200.200.200.200, iptables can convert IP from 10.24.1.x to IP from 200.200.200.200, like the host request Google.

Postgresql Indexes

Introduction

Indexes will speed up your read(SELECT) and write(INSERT, UPDATE, DELETE) operation on a table, but they should by removed when a query seldom or never used. Create a bit table’s index will spend lot of time. By default, PostgreSQL allows reads (SELECT statements) to occur on the table in parallel with index creation, but writes (INSERT, UPDATE, DELETE) are blocked until the index build is finished. In production environments this is often unacceptable. It is possible to allow writes to occur in parallel with index creation, but there are several caveats to be aware of — for more information see Building Indexes Concurrently.

Index Types

PostgreSQL provides several index types: B-tree, Hash, GiST, SP-GiST and GIN. By default, the CREATE INDEX command creates B-tree indexes, which fit the most common situations.

Multicolumn index

Currently, only the B-tree, GiST and GIN index types support multicolumn indexes. Up to 32 columns can be specified. (This limit can be altered when building PostgreSQL; see the file pg_config_manual.h.)

if your frequently query is like this: SELECT name FROM test2 WHERE major = constant AND minor = constant;, your need create an index on table test2 with major, minor columns: CREATE INDEX test2_mm_idx ON test2 (major, minor);

The order is important in multicolumn index:

A multicolumn B-tree index can be used with query conditions that involve any subset of the index’s columns, but the index is most efficient when there are constraints on the leading (leftmost) columns. The exact rule is that equality constraints on leading columns, plus any inequality constraints on the first column that does not have an equality constraint, will be used to limit the portion of the index that is scanned. Constraints on columns to the right of these columns are checked in the index, so they save visits to the table proper, but they do not reduce the portion of the index that has to be scanned. For example, given an index on (a, b, c) and a query condition WHERE a = 5 AND b >= 42 AND c < 77, the index would have to be scanned from the first entry with a = 5 and b = 42 up through the last entry with a = 5. Index entries with c >= 77 would be skipped, but they’d still have to be scanned through. This index could in principle be used for queries that have constraints on b and/or c with no constraint on a — but the entire index would have to be scanned, so in most cases the planner would prefer a sequential table scan over using the index.

Order By

By default, B-tree indexes store their entries in ascending order with nulls last.

Combining Multiple Indexes

little difficult just trade off to decide which indexes to provide. Sometimes multicolumn indexes are best, but sometimes it’s better to create separate indexes and rely on the index-combination feature.

Index on Expressions

This kind of index, not a specific column, it’s an expression: CREATE INDEX people_names ON people ((first_name || ' ' || last_name));

Partial Index

CREATE INDEX idx_xxx ON table(name) WHERE NOT deleted this index only enables to rows which deleted is TRUE

Python-main-py

python的__main__.py文件,通常,一个package下有一个__init__.py文件标识这是package,同样可以有一个__main__.py文件,有了后你就可以这样运行一个脚本:python script_dir或者把这个dir打包成zip,可以使用python zipball.zip来执行,python会执行__main__.py中的语句。

Disable-keyboard-on-ubuntu

有时候不接外置显示器的时候,喜欢把键盘压在笔记本键盘上方使用,但如果不禁用内置键盘的话就会有误操作的风险,所以这样做,利用ubuntu中的xinput

查看设备使用xinput list

1
2
3
4
5
6
7
8
9
10
11
12
⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ SynPS/2 Synaptics TouchPad                id=11   [slave  pointer  (2)]
⎜   ↳ Logitech USB-PS/2 Optical Mouse           id=12   [slave  pointer  (2)]
⎜   ↳ Logitech Unifying Device. Wireless PID:4004   id=13   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Video Bus                                 id=7    [slave  keyboard (3)]
    ↳ Sleep Button                              id=8    [slave  keyboard (3)]
    ↳ Acer CrystalEye webcam                    id=9    [slave  keyboard (3)]
    ↳ AT Translated Set 2 keyboard              id=10   [slave  keyboard (3)]

找到内置键盘,我这里是那个叫"AT Translated Set 2 keyboard"的,id是10,禁用使用:xinput float 10

如果再启用使用xinput reattach 10 3,3标识这个设备的master的id,从list的结果很容易看到从属关系。