Thursday, August 11, 2022

Setup autostart services in Linux with SELinux


1) Create your start / stop script in a predefined directory (e.g. /development/service-script/ )

  • /development/service-script/start-cmd
  • /development/service-script/stop-cmd

2) Allow SELinux to execute binaries in the predefined directory /development/service-script/ (!! important for SELinux)

    chcon -R -t bin_t /development/service-script/


3) Create abc.service in /etc/systemd/system/

    # Systemd unit file for ABC service

    [Unit]
 
    Description=ABC service
    After=syslog.target network.target

    [Service]
    Type=forking

    ExecStart=/development/service-script/start-cmd
    ExecStop=/development/service-script/stop-cmd

    User=service_owner
    Group=service_owner
    UMask=0007
    RestartSec=10
    Restart=always

    [Install]
    WantedBy=multi-user.target


4) Reload systemd

    systemctl daemon-reload

5) Start ABC service

    systemctl start abc


6) If ABC service is working, then we can enabled it for autostart

    systemctl enable abc



Wednesday, August 10, 2022

NO_PUBKEY when updating QGIS in Linux / Ubuntu (2022)

Update the key file (qgis-archive.gpg) by:


wget  -qO  -  https://qgis.org/downloads/qgis-2022.gpg.key  |  gpg  --no-default-keyring  --keyring  gnupg-ring:/etc/apt/trusted.gpg.d/qgis-archive.gpg  --import


The NO_PUBKEY error message will be gone for 'apt update'


Sunday, June 5, 2022

Separated dock for multiple workspace in Ubuntu

Separated dock for multiple workspace in Ubuntu, set the following to be true:

gsettings set org.gnome.shell.extensions.dash-to-dock isolate-workspaces true

Sunday, May 29, 2022

Skip basic authentication headers before passing a request to proxypass target host

This can be done via "RequestHeader unset Authorization" 


<Location "/some_path">

    Require all granted

    ProxyPass https://target-host

    RequestHeader unset Authorization

</Location>


Reference: 1, 2

Monday, January 24, 2022

Extract PDF content (from CHP) with Python

import re

import sys

import urllib.request

import pdfplumber

import pandas as pd



if (len(sys.argv) < 2):

    print("\n\nSyntax: python extract_pdf.py date_string (e.g. 20220124) \n\n")

    exit()


def main():    

    date_string  = sys.argv[1] # e.g. 20220124

    pdf_file_name = f"ctn_{date_string}.pdf" # PDF from CHP: https://www.chp.gov.hk/files/pdf/ctn_20220124.pdf

    #download_pdf( pdf_file_name )

    extract_pdf( pdf_file_name )



def extract_pdf( pdf_file_name ):

    with pdfplumber.open( f"./pdf/{pdf_file_name}" ) as pdf:

        for page in pdf.pages:

            #print(page)

            for table in page.extract_tables():

                df = pd.DataFrame(table[1:], columns=table[0])

                for index, row in df.iterrows():

                    if (isinstance(row[0], str) and len(row[0])>0):

                        rowid = row[0].replace(".","")

                        title = row[1].split("\n")

                        for i in range(0,len(title)):                            

                            if (re.search(u'[\u4e00-\u9fff]', title[i]) is None):

                                title[i] = ""

                        print(rowid, "".join(title))


def download_pdf ( pdf_file_name ) :

    pdfFile = urllib.request.urlopen(f"https://www.chp.gov.hk/files/pdf/{pdf_file_name}")

    file = open(f"./pdf/{pdf_file_name}", "wb")

    file.write(pdfFile.read())

    file.close()



main()

Display cx_oracle error indicating which rows are affected

cursor.executemany("SQL EXEC STATEMENT", data, batcherrors=True)

for error in cursor.getbatcherrors():

    print("Error", error.message, "at row offset", error.offset) 



Sunday, January 23, 2022

Calculate the viewing location in Cesium

 Here I summarise two approach for calculating the viewing location in Cesium viewer:


Method 1 (using Camera.computeViewRectangle() method) 


var projection = new Cesium.WebMercatorProjection();

var rect = new Cesium.Rectangle()

viewer.camera.computeViewRectangle(projection.ellipsoid, rect)


let rect_x = (rect.east - rect.west)/2 + rect.west;

let rect_y = (rect.north - rect.south)/2 + rect.south;


var rect_lon = Cesium.Math.toDegrees(rect_y);

var rect_lat = Cesium.Math.toDegrees(rect_x);


console.log(rect_lat, rect_lon)


Note: The computeViewRectangle( ) could be very large when the view pitch is very flat, resulting in a very far point being calculated.


Method 2 (using Camera.computeViewRectangle() method) 


var cc = document.getElementById("cesiumContainer");

var screenCenterPt = new Cesium.Cartesian2(cc.offsetWidth/2, cc.offsetHeight/2);

var pick = viewer.scene.globe.pick(viewer.camera.getPickRay(screenCenterPt), viewer.scene);

if (pick) {

  var geoPt = viewer.scene.globe.ellipsoid.cartesianToCartographic(pick);

  var point = [geoPt.longitude/ Math.PI * 180, geoPt.latitude/ Math.PI * 180];

  

  var rect_lon = point[0];

  var rect_lat = point[1];

  

  console.log(rect_lat, rect_lon);

}


Note: It uses screen center to calculate the point, seems to be more useful.

Thursday, January 6, 2022

DOS batch file: Expand * into list of filenames in command line

expand-wildcard.bat

@echo off

setlocal EnableDelayedExpansion


set params=command

for %%a in ("%~1") do (

    set params=!params! %%a

)


echo %params%

%params%

 

Then, running the following command:

C:\>expand-wildcard filename*


Will be executed as following:

C:\>command filename1 filename2 filename3 filename4 ..

Sync multiple git repo at once

Use the following command in Linux will do the job:  ls -d RepoNames* | xargs -I{} git -C {} pull