小帆船

曾梦回大航海时代
穿过海上丝路的迷雾
带领大明的船队
发现蛮荒待垦的新大陆

曾化身杰克船长
穿梭于世界的尽头
驾着飞翔的荷兰人
化解黑珍珠的诅咒

曾敬佩翟墨真汉子
向西方出发,从东方归航
郑和的风帆落下太久
谁还记得大海的模样?

曾感叹云天明
来了 爱了 临走送她一颗星
乘着核爆推动的太阳帆
讲述童话中的黑暗森林

曾听见水手说
风雨中这点痛算什么
不要怕
至少我们还有梦

孤独航行的小帆船
仍梦想四海扬帆
底下是大海的沉静碧蓝
头顶是金阳灿烂

* 句子多有借鉴 请多包涵

FireFox for Mac中文字体粗细大小不一的解决办法(默认英文)

我的Firefox for Mac 一直有这个问题,某些中文网站字体显示粗细大小不一。如图:

困扰我很久,参考知乎的答案:
https://www.zhihu.com/question/19586802

答案中的用户把中文zh放在了en之前,结果访问很多国外网站比如Airbnb, Kayak时,它们默认我来自中国(因为zh-cn排第一嘛)。把界面,货币等都默认为中国,对于在海外学习生活的我们不是很方便。

解决办法是:把en-US(如果在美国),en放在zh-cn之前。

这样访问英文网站没问题,中文字体也没问题。效果如下图:

设置Firefox / Preferences / Content / Languages

你也可以加入zh-hk,zh-tw以便访问这些地区的繁体网站。如图:

Seasons of Los Angeles 洛城四季

最后的叶子落下的时候 When last leaf falls
你和冬天一起来到我身边 Along with Winter you come to me
海都不动了 Ocean remains still
我把蓝天给了你 I give you sky
把蓝色留给自己 Leaving myself the blue

第一朵蓝花楹绽开的时候 When first Jacaranda blooms
你和春天一起拂过窗前 Along with Spring you pass my window
星都不闪了 Stars no longer glow
我把雪山给了你 I give you snow peaks
把冰川留给自己 Leaving myself the ice

排排棕榈摇曳的时候 When palm trees waver
你和夏天一起漫过沙滩 Along with Summer you rush to shore
鸥都唱累了 Seagulls tired of singing
我把浪花给了你 I give you breakers
把涛声留给自己 Leaving myself the tides

满树桔子红了的时候 When oranges turn yellow
你和秋天一起掠过山林 Along with Autumn you glide across ridges
大地都燃烧了 Land is burning
我把晚霞给了你 I give you sunset
把暮光留给自己 Leaving myself the twilight

最初的雪花融化的时候 When first snowflake melts
你走过四季回到我身边 Through four seasons you back to me
心稳稳在跳 Heart goes on beating
我把生命给了你 I give you my life
把意义留给自己 Leaving myself the meaning

——
第一段是本科时候在网上闲逛偶遇某人签名档,当时抄下来,作者无从查起。
后面四段扩写 作于 2018.2.10 洛杉矶

Template rendered html email for Web2py email verification and password reset

For discussion about this old problem, read Google group thread here.

I ended up modifying gluon/tools.py. It is probably not a good practice. But it is the easiest solution.

I edit register() and email_reset_password()

modifying something like (depends on which one)

message=self.messages.verify_email % d

to

message=('',response.render('email/template.html', d))

Be careful with the ending parentheses, the two functions need different number of them due to context codes.

It is important to use a 2-tuple or 2-list to pass the second item to html in the email, the empty '' will go to text. Otherwise, it will likely be sent as plain text, especially if you have <!DOCTYPE as start in your template.

for email_reset_password(), you also need:

response = current.response

Then you need to delete tools.pyc and restart web2py to take effect.

Make sure you modify tools.py and delete tools.pyc every time you update web2py.

Hope this save some other people’s time.

Force SSL/HTTPS and non-www in web2py

Update 02.08.2018: Code is updated to use just one line to force https:

request.requires_https()

=======

I read this

https://groups.google.com/forum/#!topic/web2py/RzJ4pYtAWF4

and

https://stackoverflow.com/questions/26802850/pythonanywhere-web2py-redirect-to-https

then I realized “cronjob” problem described in these answers are no longer relevant since `scheduler` has long since replaced `cron`

I created a new model secure.py and add:

########## FORCED SSL non-www ##########
session.secure()
if not request.is_https:
    redirect(URL(scheme='https', args=request.args, vars=request.vars))
request.requires_https()
if request.env.http_host.startswith("www."):
    redirect(URL(host=request.env.http_host[4:]))
#####################################

I skipped the cron part since scheduler has long since replaced cron in web2py.

I created separated model so I can specify only to have it on my server, not on my local macbook, using .gitignore (see #2 below)

2. I need only to use https at server, not local development environment (127.0.0.1:8000), so I put models/secure.py into my .gitignore

Hope this helps!

China Vibe

Vined / Pixabay

Original: Walk Off The Earth – Summer Vibe
Adapted by Yi Liu

EH-O, EH-O, EH-O, BOP BOP AWAY-O

China vibe, China vibe
I’m looking for a China vibe, got me boarding Hainan Airlines, I gotta mute those twits
Jet lag all day, trying to stay awake, wishing these smog away
I wander around Hou Hai, visit royal palace
Take a walk in Peking U, with nothing else to do
But sitting by Weimin Lake, reading a book, off the girls keeping my eyes
Taking my time

With you by my side
A Mobike ride
Cycling with the girls
Street food at night
China vibe
Looking for a China vibe

Friends paid my meals
No reason to be shamed
Bragging on the table, just listening to you
China vibe
Looking for a China vibe

I’m jonesing for clean fresh air, High Speed Rail all down to HangZhou, I’ll find friend’s place to stay
Gonna somehow, find a public square, dance this old night away
We’re drinking LongJing at Farmer’s House, tea trees all up on the hills, under the bluesky
Taking my time

With you by my side
A wood boat ride
Paddling with the girls
West Lake moonlight
China vibe
Looking for a China vibe

Kid paid our dues
With award she earned at school
Riding on dad’s back, just staring at you
China vibe
Looking for a China vibe

And the train arrives home
But I’ll leave again tomorrow
Oh
EH-O, EH-O, EH-O BOP BOP AWAY-O

With you by my side
A Didi ride
Jamming with the girls
Karaoke all night
China vibe
Looking for a China vibe

Love my parents
Got nothing to prove
Sitting by your side, just listening to you
China vibe
Looking for a China vibe

EH-O, EH-O, EH-O BOP BOP AWAY-O
China vibe, China vibe

EH-O, EH-O, EH-O BOP BOP AWAY-O
China vibe, looking for a China vibe

Securing Web2py with Let’s Encrypt / Certbot

In case anybody wondering the same question about using certbot/let’s encrypt and web2py: how do you serve the .well-known folder for certification, when all the request goes to wsgi handler?

1. use `–standalone` as David advised. But you have to stop the web server every time you renew.

2. instead, you can use the standard `–webroot` method. Here, you need to edit your vhost file be it apache or nginx, add a location block:

Using nginx for example:

location /.well-known {
    root /home/www-data/web2py;
}

This way, nginx will server the .well-known and skip passing it onto uwsgi/web2py. Make sure you restart nginx after making this server conf change and use

sudo certbot certonly/renew --webroot -w /home/www-data/web2py -d example.com -d www.example.com

Passenger WSGI setup with pyenv on Dreamhost for Web2Py

I have been using fastcgi+flup (link) to run my web2py apps on shared Dreamhost hosting. But the speed was really mediocre. Dreamhost recommends Passenger WSGI for python application.

After hours of research and testing, I would like to share my experience using pyenv + passenger wsgi + web2py on Dreamhost shared hosting as of 08.2017

What I did differently than most guides online is that I only have to edit .htaccess file (in domain root folder) with: (Credit: ASO)

PassengerEnabled on
PassengerAppRoot /home/%USER%/
PassengerPython /home/%USER%/.pyenv/shims/python

Most importantly and strangely, I didn’t need to modify passenger_wsgi.py (handlers/wsgihandler.py) at all. Most guides online (this; this; and many others) require adding two lines after import os, such as this one:

INTERP = "/home/%USER%/.pyenv/shims/python"
#INTERP is present twice so that the new Python interpreter knows the actual executable path
if sys.executable != INTERP: os.execl(INTERP, INTERP, *sys.argv)

But I couldn’t make it work if I modify passenger_wsgi.py. It seems .htaccess is sufficient to specify pyenv environment.

Some guides also suggest make a pyenv “virtualenv” within app folder, I found it is not required.

Assuming you already know:

  1. how to use web2py
  2. how to use pyenv on Dreamhost
  3. Read about Passenger on Dreamhost

This is what I did:

  1. Enable passenger on Dreamhost panel. A folder public will be created. Don’t worry.
  2. Put web2py files into your domain root folder, which is parent folder of public
  3. cp handlers/wsgihandler.py passenger_wsgi.py
  4. Create/modify .htaccess in domain root folder as described above.
  5. Created tmp/ folder under my web root folder, did a touch restart.txt to get passenger to reload

Your web2py site should now load in your browser. If you use free “Let’s Encrypt” SSL from Dreamhost panel, you should be able to verify your pyenv python environment from admin interface by accessing https. I did verify mine.

I am not sure ssh tunnel method could serve as verification, because you are serving admin from a separate web2py instance running from your shell.

Hope this will help fellow web2py users. Thank all the web2py team for providing web2py.

Add Bluetooth or Inline Remote Mic Cable to Koss KSC75 Headphone

Koss KSC75 is a legendary on-ear clip headphone. It provides stunning high-fidelity sound with unbeatable price. All the 5 star reviews say it all.

I have two of these. One had a wire problem near the plug. I need to replace the cable. I always want to add inline remote and mic to the KSC75 so I can use the headphone more conveniently with my smartphone.

For the other one, which is still perfectly working, I want to convert to a bluetooth headphone. Here is what I have after some simple sodlering.

Opening KSC75:


You carefully remove the ear clip and plastic cover to reveal the solder points.

Inline remote and mic cable KSC75:

I bought this DIY inline remote and mic cable from AliExpress for less than $3.

Bluetooth KSC75:

I bought this DIY bluetooth cable from AliExpress for about $11. It is bluetooth 4.0. Now I have both the convenience of Bluetooth and superior sound of KSC75.