约拿的悔改祷告



说:我遭遇患难求告耶和华,你就应允我;从阴间的深处呼求,你就俯听我的声音。 (约拿书 2:2 和合本)
He said: “In my distress I called to the Lord , and he answered me. From deep in the realm of the dead I called for help, and you listened to my cry.  (Jonah 2:2 NIV)
你将我投下深渊,就是海的深处;大水环绕我,你的波浪洪涛都漫过我身。 (约拿书 2:3 和合本)
You hurled me into the depths, into the very heart of the seas, and the currents swirled about me; all your waves and breakers swept over me.  (Jonah 2:3 NIV)
我说:我从你眼前虽被驱逐,我仍要仰望你的圣殿。 (约拿书 2:4 和合本)
I said, ‘I have been banished from your sight; yet I will look again toward your holy temple.’  (Jonah 2:4 NIV)
诸水环绕我,几乎淹没我;深渊围住我;海草缠绕我的头。 (约拿书 2:5 和合本)
The engulfing waters threatened me, the deep surrounded me; seaweed was wrapped around my head.  (Jonah 2:5 NIV)
我下到山根,地的门将我永远关住。耶和华—我的 神啊,你却将我的性命从坑中救出来。 (约拿书 2:6 和合本)
To the roots of the mountains I sank down; the earth beneath barred me in forever. But you, Lord my God, brought my life up from the pit.  (Jonah 2:6 NIV)
我心在我里面发昏的时候,我就想念耶和华。我的祷告进入你的圣殿,达到你的面前。 (约拿书 2:7 和合本)
“When my life was ebbing away, I remembered you, Lord , and my prayer rose to you, to your holy temple.  (Jonah 2:7 NIV)
那信奉虚无之神的人,离弃怜爱他们的主; (约拿书 2:8 和合本)
“Those who cling to worthless idols turn away from God’s love for them.  (Jonah 2:8 NIV)
但我必用感谢的声音献祭与你。我所许的愿,我必偿还。救恩出于耶和华。 (约拿书 2:9 和合本)
But I, with shouts of grateful praise, will sacrifice to you. What I have vowed I will make good. I will say, ‘Salvation comes from the Lord .’ ”  (Jonah 2:9 NIV)


How to fix error : no module named sendgrid when try to use sendgrid python lib in PHP.


"no module named sendgrid" error reported with below codes:

<?php
system("/usr/bin/python sendmail.py 2>&1");
system("/usr/bin/python --version 2>&1", $ret);
?>

sendmail.py

import sendgrid
import os
from sendgrid.helpers.mail import *

sg = sendgrid.SendGridAPIClient(apikey=os.environ.get('SENDGRID_API_KEY'))
from_email = Email("test@example.com")
to_email = Email("test@example.com")
subject = "Sending with SendGrid is Fun"
content = Content("text/plain", "and easy to do anywhere, even with Python")
mail = Mail(from_email, subject, to_email, content)
response = sg.client.mail.send.post(request_body=mail.get())
print(response.status_code)
print(response.body)
print(response.headers)
....




nginx config your websites' favicon

        1. vim nginx.conf
        # set site favicon
        location /favicon.ico {
            root html;
        }

       2. place a favicon.ico file under html/

       3. optional, add below codes to your index.html.
<link rel="icon" href="/favicon.ico" mce_href="/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="/favicon.ico" mce_href="/favicon.ico" type="image/x-icon">    



        # set site favicon
        location /favicon.ico {
            root html;
        }

How to extend file extensions to be parsed by PHP

sudo vim /etc/php/7.0/fpm/pool.d/www.confsudo vim /etc/php/7.0/fpm/pool.d/www.conf
By default, PHP only parse files with .php extension.
We can extend extensions with security.limit_extensions directive.

sudo vim /etc/php/7.0/fpm/pool.d/www.conf
sudo vim /etc/php/7.0/fpm/pool.d/www.conf
; Limits the extensions of the main script FPM will allow to parse. This can
; prevent configuration mistakes on the web server side. You should only limit
; FPM to .php extensions to prevent malicious users to use other extensions to
; exectute php code.
; Note: set an empty value to allow all extensions.
; Default Value: .php
; You can add any extensions you want to be parsed as php
security.limit_extensions = .php .php3 .php4 .php5 .php7 .ler

sudo service php7.0-fpm restart

Config nginx:

/etc/nginx/nginx.conf
        location ~ \.(php|ler)$ {
            include fastcgi.conf;
            fastcgi_pass   unix:/run/php/php7.0-fpm.sock;
        }

        location ~ \.(php|ler)$ {
            root vhosts/$root_name;
            include fastcgi.conf;
            fastcgi_pass   unix:/run/php/php7.0-fpm.sock;
        }
sudo service php7.0-fpm restart 

sudo service nginx restart

Let's do the test.

cat index.ler<?php
phpinfo();
?>
.ler parsed as .php too, works well.

How to set up LNMP(linux+nginx+mysql+php) developer tool on your ubuntu server

Install all software:
sudo apt-get install nginx
sudo apt-get install php7.0-fpm
sudo apt-get install php7.0-curl
sudo apt-get install php7.0-gd php7.0-mcrypt php7.0-mysql
sudo apt-get install mysql-server mysql-client

Please remember your mysql database root password!!!

Let's config up.

1. Add nginx user and group, nginx server and php-fpm will run as nginx user.
sudo groupadd nginx 
sudo groupadd nginx
sudo useradd -g nginx nginx
sudo service php7.0-fpm restart

2. Config php-fpm
/etc/php/7.0/fpm/php.ini
cgi.fix_pathinfo=0

/etc/php/7.0/fpm/pool.d/www.conf
listen = /run/php/php7.0-fpm.sock
listen.owner = nginx
listen.group = nginx

sudo service php7.0-fpm restart

3. Config nginx
/etc/nginx/nginx.conf
user nginx nginx;
location ~ \.php$ {
    include fastcgi.conf;
    fastcgi_pass   unix:/run/php/php7.0-fpm.sock;
}

sudo service nginx restart

PS:keep the user/group of php-fpm same as nginx server, I have marked as blue nginx above.


And it should not the same user that owns your virtual host directory for better security.
My websites are in vhosts folder, the user/group are errong_leng.
drwxrwxr-x  4 errong_leng errong_leng 4096 May 19 09:11 vhosts

Ok. let's do the test.
cat index.php
<?php
phpinfo();
?>

Everything looks fine.




cat index.php 
<?php
phpinfo();
?>
drwxrwxr-x  4 errong_leng errong_leng 4096 May 19 09:11 vhosts
drwxrwxr-x  4 errong_leng errong_leng 4096 May 19 09:11 vhosts
drwxrwxr-x  4 errong_leng errong_leng 4096 May 19 09:11 vhosts
drwxrwxr-x  4 errong_leng errong_leng 4096 May 19 09:11 vhosts

Send email with attachments on your google compute engine via sendgrid-python

precondition:
  1. Use the Google Cloud Launcher to sign up for the SendGrid Email service. Make a note of your SendGrid SMTP account credentials, which include username, password, and hostname. Your SMTP username and password are the same as what you used to sign up for the service. The SendGrid hostname is smtp.sendgrid.net.
  2. Create an API key:
    1. Sign in to Sendgrid and go to Settings > API Keys.
    2. Create an API key.
    3. Select the permissions for the key. At a minimum, the key will need Mail send permissions to send email.
    4. Click Save to create the key.
    5. SendGrid generates a new key. This is the only copy of the key so make sure to copy the key and save it for later.


 
Please remember your key and save it somewhere safe.
 
OK. Now we can use sendgrid python library to send email.
Of cause, you can still follow offical help to use sendgrid with other solution.
https://cloud.google.com/compute/docs/tutorials/sending-mail/using-sendgrid

install sendgrid-python 
$pip install sendgrid
 
Sample python codes:
errong_leng@blogvpn:~/algo$ cat sendmail.py
import base64
import getopt
import mimetypes
import os
import sendgrid
import sys
from sendgrid.helpers.mail import *

def useage():
    print ("python sendmail.py [-s subject] [-a attachment ] [-c cc-addr] [-b bcc-addr] [-f from-addr] [-t to-addr] to-addr . . .")
    sys.exit()

opts, args = getopt.getopt(sys.argv[1:], "ha:b:c:f:s:t:")

attachs = []
cc = []
bc = []
tc = []
from_addr = ''
subject = ''

for op, value in opts:
  if op == "-h":
      useage()
  elif op == "-a":
      attachs.append(value)
  elif op == "-b":
      bc.append(value)
  elif op == "-c":
      cc.append(value)
  elif op == "-s":
      subject = value
  elif op == "-f":
      from_addr = value
  elif op == "-t":
      tc.append(value)

if (len(args) <= 0):
    useage()

sg = sendgrid.SendGridAPIClient(apikey='REPLACEWITHYOURAPIKEY')
mail = Mail()
mail.from_email = (Email(from_addr))
mail.subject = subject
personalization = Personalization()
personalization.add_to(Email(args[0]))
for tcs in tc:
    personalization.add_to(Email(tcs))
for ccs in cc:
    personalization.add_cc(Email(ccs))
for bcc in bc:
    personalization.add_bcc(Email(bcc))
personalization.subject = subject
mail.add_personalization(personalization)

contents = args[1:]
for ct in contents:
    if (len(ct) > 0):
        mail.add_content(Content("text/plain", ct))
      
for af in attachs:
    data = ''
    with open(af, 'rb') as f:
        data = f.read()
        f.close()
    if (len(data) > 0):
        adata = base64.b64encode(data)
        attachment = Attachment()
        attachment.content = adata
        s = os.path.split(af)
        attachment.filename = s[len(s)-1]
        attachment.type = mimetypes.guess_type(attachment.filename)[0]
        attachment.disposition = "attachment"
        attachment.content_id = af
        mail.add_attachment(attachment)

response = sg.client.mail.send.post(request_body=mail.get())

print(response.status_code)
print(response.body)
print(response.headers)            
 
 
errong_leng@blogvpn:~/algo$ python sendmail.py -t "errong.leng@abc.com" -s 
"Hello" -f "errong.leng@gmail.com" -c "errong.leng@hotmail.com" 
-b "errong.leng@samsung.com" -a configs/104.199.178.17/zqzz.p12 
-a configs/104.199.178.17/zqzz.mobileconfig 
errong.leng@gmail.com "Hello with content and attachment" 
 
202

Server: nginx
Date: Fri, 19 May 2017 04:04:45 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 0
Connection: close
X-Message-Id: x7xHfWk8SmWlxUe6Ew6tmA
X-Frame-Options: DENY
Access-Control-Allow-Origin: https://sendgrid.api-docs.io
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl
Access-Control-Max-Age: 600
X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html
 
Once you see 202, which means email sending successfully. 
 
 
 

fixed: embedded-redis: Unable to run on macOS Sonoma

Issue you might see below error while trying to run embedded-redis for your testing on your macOS after you upgrade to Sonoma. java.la...