HTTP Status Code

  • 2020-1-16
Code Description
200 OK
301 Moved Permanently
302 Moved Temporarily

HTTP response status codes - MDN

JavaScript: Get current time

  • 2020-1-16
  1. Get milliseonds elapsed since January 1, 1970 00:00:00 UTC.

    1
    Date.now() // example: 1579110392189

  2. Get a Date

    1
    2
    3
    new Date()
    // examlpe1 (Chrome 81): Thu Jan 16 2020 01:55:06 GMT+0800 (China Standard Time)
    // example2 (Node 13.6.0): 2020-01-15T17:51:41.575Z

Reset a meteor project

  • 2020-1-16

Use the command meteor reset to reset your meteor project, it will clear all the data in the mongoDB.

1
meteor reset

Don't let conda change you PS1

  • 2020-1-15
1
conda config --set changeps1 False

Before:

1
(base) ➜

After:

1

在Node项目中使用import语法

  • 2020-1-12

由于历史原因,直到写作本文时,最新版本的 Node (v13.6.0) 仍不能原生支持ES模块,不能直接在 JS 文件中使用 import/export 等 ES6 标准中制定的模块加载导出语法。Node 遵循的是 CommonJS 规范,使用如 const fs = requre('fs') 这样语法去加载一个模块,这与前端领域 ES 模块写法格格不入,让我不得不得去寻求破解之法。

解决方法:

1
npm init esm

Create a new role in Rocket.Chat

We can directly edit the app/authorization/server/startup.js but remember to clear the rocketchat_permissions collection to let it take effect.

Builder, Creator and Creation

Builder

Builder is a creational design pattern that lets you construct complex objects step by step. The pattern allows you to produce different types and representations of an object using the same construction code. (Source: Builder - refactoring.guru)

You might think of creating a giant constructor with lots of parameters, which may also measure up to the above work. But it's against the No Long Parameter List rule.

A real-life example 👉IRoomBuilder, RoomBuilder

Creator

Creator is a concept from the creational design pattern - Abstract Factory.

The Abstract Factory pattern lets you produce families of related objects without specifying their concrete classes. (Source: Abstract Factory - refactoring.guru)

A real-life example 👉 ILivechatCreator (It seems that we do not apply an abstract factory pattern but a factory pattern here. Because there are no various types of livechat rooms.)

Creation

The Creation is the basic data for building a complex object. A constructor or a Builder will create more complex objects based on the Creation that passed to it.

A real-life example 👉 User

Edit nginx configurations to reverse proxy jupyterlab

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}

server {
...
location / {
proxy_pass http://jupyter;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* /(api/kernels/[^/]+/(channels|iopub|shell|stdin)|terminals/websocket)/? {
proxy_pass http://jupyter;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
...
}

Reset jupyterlab to the default status

1
2
rm ~/.jupyter/lab/workspacess/*
jupyter lab rebuild

How to create a new event handler in apps-engine repo?

Here, we put LivechatRoomClosed event as an example:

Apps-engine side

  1. Update the AppMethod enum which is under the definition/metadata directory. We will add a new method EXECUTELIVECHATROOMCLOSEDHANDLER:
1
2
3
4
...
// Livechat
EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER = 'executeLivechatRoomClosedHandler',
...
  1. Also we need to update the AppInterface enum which is under the server/compiler/AppImplements directory:
1
2
3
4
...
// Livechat
ILivechatRoomClosedHander = 'ILivechatRoomClosedHander',
...
  1. Create an interface called ILivechatRoomClosedHander.ts under the definition/livechat, its content can be similar to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { IHttp, IPersistence, IRead } from '../accessors';
import { AppMethod } from '../metadata';
import { ILivechatRoom } from './ILivechatRoom';

/**
* Handler called after a livechat room is closed.
*/
export interface ILivechatRoomClosedHander {
/**
* Method called *after* a livechat room is closed.
*
* @param livechatRoom The livechat room which is closed.
* @param read An accessor to the environment
* @param http An accessor to the outside world
* @param persistence An accessor to the App's persistence
*/
[AppMethod.EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER](data: ILivechatRoom, read: IRead, http: IHttp, persistence: IPersistence): Promise<void>;
}
  1. Edit AppListenerManager which is under the server/manager directory:

    • Add a new case into executeListener method:

    1
    2
    3
    4
    5
    6
    ...
    // Livechat
    case AppInterface.ILivechatRoomClosedHander:
    this.executeLivechatRoomClosed(data as ILivechatRoom);
    return;
    ...

    • Add executeLivechatRoomClosed method to resolve the events:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    private async executeLivechatRoomClosed(data: ILivechatRoom): Promise<void> {
    const cfLivechatRoom = Utilities.deepCloneAndFreeze(data);

    for (const appId of this.listeners.get(AppInterface.ILivechatRoomClosedHander)) {
    const app = this.manager.getOneById(appId);

    if (!app.hasMethod(AppMethod.EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER)) {
    continue;
    }

    await app.call(AppMethod.EXECUTE_LIVECHAT_ROOM_CLOSED_HANDLER,
    cfLivechatRoom,
    this.am.getReader(appId),
    this.am.getHttp(appId),
    this.am.getPersistence(appId),
    );
    }
    }