工作筆記: dz-04 9, 10, 11月 壓縮在壓縮~
Tags: angular, db-migrator, gcp, git, go, IoT-Edge, javascript, postgres, react, react-intl, vim, 工作筆記
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
-
https://docs.netlify.com/configure-builds/manage-dependencies/#node-js-and-javascript
-
在 evnironment 裡面加入
- ex: 要指定的 node version:
- NODE_VERSION V12.18.0 (2020/09/04可過) 應該跟 xlsx package 有關? XD
- ex: 要指定的 node version:
-
直接在 跟目錄下 開 .node-version or .nvmrc 檔案
Gitlab ignore ci/cd
-
https://gitlab.com/gitlab-org/gitlab/-/issues/16290
git push origin tag 'tag-name' -o ci.ckip
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
- it stores any messages that would go upstream and saves them until the device reconnects
- it acts on behalf of IoT Hub to authenticate modules and child devices so that they can continue to operate.
- 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
- taskkil /F /FID
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
- \d
- 看 table detail
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 |