7 minute read

Tags: , , , , , , , , , , ,

Go


Goland 吃 gomod 的 dependency

  • Ctrl + Alt +s > Go > Go Modules : 把 Enable Go Modules integration 打勾勾

Go Desktop application: lorca

Reader

package main

import (
	"fmt"
	"io"
	"strings"
)

func main() {
	r := strings.NewReader("Hello, Reader!")

	b := make([]byte, 8)
	for {
		n, err := r.Read(b)
		fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
		fmt.Printf("b[:n] = %q\n", b[:n])
		if err == io.EOF {
			break
		}
	}
}




CI/CD


Netlify 部屬 指定 Node.js 環境 version

Gitlab ignore ci/cd

Gitlab prevent review in ci/cd

  • Settings > CI/CD > Variables(Expand)
    • REVIEW_DISABLED: true




Javascript


Excle import 97 2003 version

if (status !== 'uploading') {
    const reader = new FileReader();
    uploadingFlag.current = false;
    reader.onload = function(e) {
      const data = new Uint8Array(e.target.result);
      // excle 97 - 2003 寫法 也過
      const arr = [];
      for (let i = 0; i !== data.length; ++i) arr[i] = String.fromCharCode(data[i]);
      const bstr = arr.join('');
      const workbook = XLSX.read(bstr, { type: 'binary' });
      /**  excle 97 2003 version 會炸
       *  const data = new Uint8Array(e.target.result)
       *  const workbook = XLSX.read(data, {type: 'array'})
       */
      /*
      *  Different worksheet
      *    - check workSheet length
      *       - workbook.SheetNames.length
      */
      const firstSheet = workbook.SheetNames[0];
      setIsReading(false);
      const elements = XLSX.utils.sheet_to_json(workbook.Sheets[firstSheet], { raw: false });
    };
    setIsReading(true);
    uploadingFlag.current = true;
    setSpinFlag(false);
    reader.readAsArrayBuffer(info.file.originFileObj);
}

How to get first and last day of the week in JavaScript

var curr = new Date; // get current date
var first = curr.getDate() - curr.getDay(); // First day is the day of the month - the day of the week
var last = first + 6; // last day is the first day + 6

var firstday = new Date(curr.setDate(first)).toUTCString();
var lastday = new Date(curr.setDate(last)).toUTCString();

firstday
"Sun, 06 Mar 2011 12:25:40 GMT"
lastday
"Sat, 12 Mar 2011 12:25:40 GMT"

Javascript checkout date range overlap

function dateRangeOverlaps(a_start, a_end, b_start, b_end) {
 if (a_start <= b_start && b_start <= a_end) return true; // b starts in a
 if (a_start <= b_end   && b_end   <= a_end) return true; // b ends in a
 if (b_start <  a_start && a_end   <  b_end) return true; // a in b
 return false;
}

Javascript remove duplicated item from array

uniq = [...new Set(array)];

Deep Copy javascript

var clonedArray = JSON.parse(JSON.stringify(nodesArray))

How to extract text from an image using JavaScript

const setImageSrc = (image: HTMLImageElement, imageFile: File) => {
 return new Promise((resolve, reject) => {
   const fr = new FileReader();
   fr.onload = function() {
     if (typeof fr.result !== 'string') {
       return reject(null);
     }
     image.src = fr.result;
     return resolve();
   };
   fr.onerror = reject;
   fr.readAsDataURL(imageFile);
 });
};




git


git tag 找出 tag 相關 commit

  • git show-ref --tags

tag 加上 message

  • git tag -a <tag> -m <message>




GCP


GCP Angular routing settings

runtime: nodejs10

env_variables:
  environment: "--prod"

handlers:

- url: /
  secure: always
  static_files: dist/index.html
  upload: dist/.*
- url: /(.*\.js)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/\1
  upload: dist/.*\.js
- url: /(.*\.css)
  secure: always
  redirect_http_response_code: 301
  static_files: dist/\1
  mime_type: text/css
  upload: dist/.*\.css
- url: /.*
  secure: always
  static_files: dist/index.html
  upload: dist/.*

Cloud Logging




React


react i18n

import React, { useState } from 'react';
import logo from './logo.svg';
import './App.css';
import { FormattedMessage, IntlProvider } from 'react-intl';
import en from './lang/en.json'
import zh from './lang/zh.json'
import { 
  Button
} from 'antd'


const locale = navigator.language;


function App() {
  const [ lang, setLang ] = useState(en)


  const test = (l) => {
    processLang(l)
    console.log(l)
  }

  const processLang = (locale) => {
    if (locale === "en") {
      setLang(en)
    } else {
      setLang(zh)
    }
  }
  return (
    <>
      <IntlProvider locale={locale} messages={lang}>
        <div>
          <Button onClick={() => test('en')} >en</Button>
          <Button onClick={() => test('zh')} >zh</Button>
        </div>
      <p> 
        <FormattedMessage
          id="app.text"
          />
      </p>
          </IntlProvider>
      </>
  );
}

export default App;
  • import by useIntl
import { FormattedMessage, useIntl } from 'react-intl';

// ...
const { formatMessage } = useIntl();
<Input placeholder={formatMessage( { id: 'workOrderReport.append.workOrder.input.text' })}/>

ant design upload image

class CustomUpload extends Component {
  state = { loading: false, imageUrl: '' };
  
  handleChange = (info) => {
    if (info.file.status === 'uploading') {
      this.setState({ loading: true });
      return;
    }
    if (info.file.status === 'done') {
      getBase64(info.file.originFileObj, imageUrl => this.setState({
        imageUrl,
        loading: false
      }));
    }
  };

  beforeUpload = (file) => {
    const isImage = file.type.indexOf('image/') === 0;
    if (!isImage) {
      AntMessage.error('You can only upload image file!');
    }
    
    // You can remove this validation if you want
    const isLt5M = file.size / 1024 / 1024 < 5;
    if (!isLt5M) {
      AntMessage.error('Image must smaller than 5MB!');
    }
    return isImage && isLt5M;
  };

  customUpload = ({ onError, onSuccess, file }) => {
    const storage = firebase.storage();
    const metadata = {
        contentType: 'image/jpeg'
    }
    const storageRef = await storage.ref();
    const imageName = generateHashName(); //a unique name for the image
    const imgFile = storageRef.child(`Vince Wear/${imageName}.png`);
    try {
      const image = await imgFile.put(file, metadata);
      onSuccess(null, image);
    } catch(e) {
      onError(e);
    }
  };
  
  render () {
    const { loading, imageUrl } = this.state;
    const uploadButton = (
    <div>
      <Icon type={loading ? 'loading' : 'plus'} />
      <div className="ant-upload-text">Upload</div>
    </div>
    );
    return (
      <div>
        <Upload
          name="avatar"
          listType="picture-card"
          className="avatar-uploader"
          beforeUpload={this.beforeUpload}
          onChange={this.handleChange}
          customRequest={this.customUpload}
        >
          {imageUrl ? <img src={imageUrl} alt="avatar" /> : uploadButton}
        </Upload>
      </div>
    );
  }
}




Microsoft


Microsoft: IoT Edge

  • https://docs.microsoft.com/en-us/azure/iot-edge/offline-capabilities

  • Offline Capabilites

    1. it stores any messages that would go upstream and saves them until the device reconnects
    2. it acts on behalf of IoT Hub to authenticate modules and child devices so that they can continue to operate.
    3. it enables communication between child devices that normally would go through IoT Hub.

Window nginx

  • check running nginx
C:\nginx-1.19.3>tasklist /fi "imagename eq nginx.exe"

映像名稱                       PID 工作階段名稱      工作階段 #    RAM使用量
========================= ======== ================ =========== ============
nginx.exe                    21920 Console                    2      6,940 K
nginx.exe                     9452 Console                    2      7,744 K
nginx.exe                    18912 Console                    2      7,012 K
nginx.exe                    12124 Console                    2      7,320 K
nginx.exe                    18612 Console                    2      7,024 K
nginx.exe                    24164 Console                    2      7,364 K
nginx.exe                    26388 Console                    2      7,048 K
nginx.exe                    10920 Console                    2      7,392 K
nginx.exe                     7076 Console                    2      7,064 K
nginx.exe                     6784 Console                    2      7,396 K
nginx.exe                     4092 Console                    2      7,300 K
nginx.exe                    13640 Console                    2      7,632 K
nginx.exe                    12520 Console                    2      7,348 K
nginx.exe                     9980 Console                    2      7,672 K
nginx.exe                     4256 Console                    2      7,488 K
nginx.exe                    15924 Console                    2      7,820 K
nginx.exe                    23028 Console                    2      7,464 K
nginx.exe                    10992 Console                    2      7,828 K
  • kill pid
    • taskkil /F /FID PID-name
C:\nginx-1.19.3>taskkill /F /PID 21920
成功: 處理程序 PID 21920 已經終止了。

  • service 寫法
    server {
       listen 80;
       server_name login.127.0.0.1.xip.io;

       location / {
           proxy_pass http://localhost:3001;
       }
    }

    server {
       listen 80;
       server_name sfr.127.0.0.1.xip.io;

       location / {
           proxy_pass http://localhost:3000;
       }
    }

nginx

  • start
    • nginx
  • stop
    • nginx -s sotp




vim


vim

  • gg
    • 到最上面
  • 大G
    • 到最下面
  • Crtl + f
    • 上一頁
  • Ctrl + b
    • 下一頁
  • u
    • 上一步
  • yy
    • copy
  • 小 p
    • past 下一行
  • 大 p
    • past 上一行
  • x
    • 刪掉一個字型
  • dd
    • 刪掉一整行
  • d + G
    • 從本行刪到最後一行
  • d + GG
    • 從本行刪到第一行
  • / ${words}
    • 搜尋
  • n
    • 看找到的 next ${words}
  • shift + n
    • 找上一筆 找到的 ${words}
  • w
    • 到下一個字元的尾巴
  • 0
    • 到行數的第一個位置
  • $
    • 到行數最後一個位置
  • ex: 到 第50行 的 第7個字 刪掉後兩個字

    • 50 gg 7 | xx

postgres


postgres array type

CREATE TABLE sal_emp (
    name            text,
    pay_by_quarter  integer[],
    schedule        text[][]
);

db-migrator

  • sql 檔案 好像都要 double “” 才會過

  • psql

    • 看 table detail
      • \d

alter column

CREATE TABLE assets (
    id serial PRIMARY KEY,
    name TEXT NOT NULL,
    asset_no VARCHAR NOT NULL,
    description TEXT,
    location TEXT,
    acquired_date DATE NOT NULL
);

INSERT INTO assets(name,asset_no,location,acquired_date)
VALUES('Server','10001','Server room','2017-01-01'),
      ('UPS','10002','Server room','2017-01-01');



ALTER TABLE assets 
ALTER COLUMN name TYPE VARCHAR;



ALTER TABLE assets 
    ALTER COLUMN location TYPE VARCHAR,
    ALTER COLUMN description TYPE VARCHAR;
  • PostgreSQL issued an error and a very helpful hint:
ALTER TABLE assets 
ALTER COLUMN asset_no TYPE INT;


-- ERROR:  column "asset_no" cannot be cast automatically to type integer
-- HINT:  You might need to specify "USING asset_no::integer".


ALTER TABLE assets
ALTER COLUMN asset_no TYPE INT 
USING asset_no::integer;

  • 自己實驗 int 改 varchar
dev_tenant=# \d test;
                Table "public.test"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 id     | text    |           | not null | 
 lol    | integer |           | not null | 

dev_tenant=#  yutingwu  (e) base  ~  docker exec -it postgres psql -U postgres
psql (11.9)
Type "help" for help.

postgres=# \c dev_teant;
FATAL:  database "dev_teant" does not exist
Previous connection kept
postgres=# \c dev_tenant;
You are now connected to database "dev_tenant" as user "postgres".
dev_tenant=# \d test;
                     Table "public.test"
 Column |       Type        | Collation | Nullable | Default 
--------+-------------------+-----------+----------+---------
 id     | text              |           | not null | 
 lol    | character varying |           | not null |