Change the category title color and thickness of scrollbar on Blockly

Blockly의 처음 인상은 굉장히 단순해 보인다. 몇가지만 수정하면 좀더 이쁘게 보일수 있을 것 같은데, 일단은 코드 상에서 해결해야 하는 제목에서 보이는 두 내용을 적용하도록 수정해본다.

소스 파일의 내용 기준은 현재 가장 최신버전인 blockly-3.20191014.4를 기준으로 한다. 추후 업데이트 되더라도 큰 차이는 없을테니 잘 찾아서 적용하면 될듯.

Scrollbar Thickness

blockly-3.20191014.4/core/scrollbar.js [301:305]

Blockly.Scrollbar.scrollbarThickness = 15;
if (Blockly.Touch.TOUCH_ENABLED) {
  Blockly.Scrollbar.scrollbarThickness = 25;
}

위 두 값 (15, 25)를 원하는 값으로 수정. 대략 4, 8 정도면 적당한 듯.

Category Title Color

blockly-3.20191014.4/core/toolbox.js [259:275]

Blockly.Toolbox.prototype.handleBeforeTreeSelected_ = function(node) {
  if (node == this.tree_) {
    return false;
  }
  if (this.lastCategory_) {
    this.lastCategory_.getRowElement().style.backgroundColor = '';
    this.addColour_(); // add
  }
  if (node) {
    var hexColour = node.hexColour || '#57e';
    node.getRowElement().style.backgroundColor = hexColour;
    node.getRowElement().getElementsByTagName('span')[1].style.color = '#fff'; // add
    // Add colours to child nodes which may have been collapsed and thus
    // not rendered.
    this.addColour_(node);
  }
  return true;
};

blockly-3.20191014.4/core/toolbox.js [605:627]

Blockly.Toolbox.prototype.addColour_ = function(opt_tree) {
  var tree = opt_tree || this.tree_;
  var children = tree.getChildren(false);
  for (var i = 0, child; child = children[i]; i++) {
    var element = child.getRowElement();
    if (element) {
      if (this.hasColours_) {
        var border = '8px solid ' + (child.hexColour || '#ddd');
        var colour = child.hexColour || '#000'; // add
      } else {
        var border = 'none';
        var colour = '#000'; // add
      }
      element.getElementsByTagName('span')[1].style.color = colour; // add
      if (this.workspace_.RTL) {
        element.style.borderRight = border;
      } else {
        element.style.borderLeft = border;
      }
    }
    this.addColour_(child);
  }
};

위와 같이 // add 라고 되어 있는 줄을 함수 내에 추가하고, blockly 디렉토리 내에서 빌드를 해보면,

$ ./build.py

압축된 javascript 파일이 생성된다. 이를 이용하여 데모페이지를 보게 되면,

정해진 카테고리의 테마 색상에 따라, 카테고리의 타이틀 색상과 스크롤바의 크기 역시 세련되게 변경 됨을 볼 수 있다.

sha256sum을 이용해 파일의 유효성을 검증해보기

Ubuntu나 Raspbian 등 운영체제를 설치하기 위해선 해당 배포 웹페이지에서 iso 파일을 받게 된다. 보통 배포되는 웹페이지를 보면 파일과 함께 md5, sha256 파일이 같이 보여지게 되는데, 이를 이용해 내가 다운로드 받은 파일이 제대로 받아진 것인지를 확인할 수 있다.

macOS나 Ubuntu에선 기본으로 sha 관련 툴이 제공된다. 먼저 다운로드 받은 파일의 sha256 hash 코드를 확인해보려면,

$ shasum -a 256 ubuntu-18.04.3-desktop-amd64.iso
add4614b6fe3bb8e7dddcaab0ea97c476fbd4ffe288f2a4912cb06f1a47dcfa0  ubuntu-18.04.3-desktop-amd64.iso

결과로 다음과 같이 hash 코드가 생성되고 파일명을 같이 보여준다. 이를 위에서 보여졌던 SHA256SUMS 파일을 받아 비교해 보면,

$ cat SHA256SUMS.txt 
add4614b6fe3bb8e7dddcaab0ea97c476fbd4ffe288f2a4912cb06f1a47dcfa0 *ubuntu-18.04.3-desktop-amd64.iso
b9beac143e36226aa8a0b03fc1cbb5921cff80123866e718aaeba4edb81cfa63 *ubuntu-18.04.3-live-server-amd64.iso

눈으로 하나 하나 비교해봐도 되겠지만, 검사 기능도 역시 지원한다.

$ shasum -a 256 -c SHA256SUMS.txt               
ubuntu-18.04.3-desktop-amd64.iso: OK
shasum: ubuntu-18.04.3-live-server-amd64.iso: 
ubuntu-18.04.3-live-server-amd64.iso: FAILED open or read
shasum: WARNING: 1 listed file could not be read

받을 파일 중 ubuntu-18.04.3-desktop-amd64.iso는 무결함을 검증하였다. 이제 안심하고 이 이미지 파일을 사용할 수 있게 된다.

Install Confluence Server on VPS

Confluence (https://www.atlassian.com/ko/software/confluence)는 협업 문서 작성 도구로 잘 알려져 있는 툴이다. 많은 개발 회사들에 사용하는 것으로 알려져 있다. 무료는 아니고, 클라우드 서비스, 설치형 둘다 제공한다.

한번 써보고자 시도해 봤는데 (그냥 새로운 걸 좋아하는 취지에서…) 클라우드 서비스를 사용하려면, 한달에 $10을 내야 한다. 현재 블로그를 운용하는 VPS가 약간은 잉여인지라, 거기에 추가해보면 어떨까 해서 다시 삽질을 시작해봤다.

설치는 대단히 간단하다. 서버에 설치 스크립트 파일을 저장하고, 이를 루트 권한으로 실행하면 끝.

설치 방법은 https://confluence.atlassian.com/doc/installing-confluence-on-linux-143556824.html에 나와 있는대로, 몇번 엔터키만 툭탁하면 설치는 완료.

한글 관련 문제가 있어, 데이터베이스를 생성할 때, utf-8을 기본값으로 설정해야 한다. 이 작업을 하지 않으면, 한글 문서를 적어도 깨져보이는 에러가 발생한다.

mysql 설정, 파일에 다음의 두 라인 추가

/etc/mysql/mysql.conf.d/mysqld.cnf

[mysqld]
...
character_set_server=utf8
collation-server=utf8_bin 

데이터베이스 생성

$ mysql -u root -p

mysql> CREATE DATABASE <database-name> CHARACTER SET utf8 COLLATE utf8_bin;
mysql> GRANT ALL PRIVILEGES ON <database-name>.* TO '<confluenceuser>'@'localhost' IDENTIFIED BY '<password>';

기본 접근 경로는 http://<your_domain>:8090 이다. 처음 접속 시 라이센스 및 데이터베이스 관련 설정을 해야 하고, 약간의 시간이 걸리고 나면 완료.

설치형은 $10를 한번만 지불하면 된다. 물론 기술지원 (메이저 업데이트)을 위해선 1년마다 $10을 지불해야 하지만, 납득할 만한 가격인듯.

다음으로 현재 블로그에 사용하는 SSL을 이용해, 보안접속이 가능하도록 설정한다.

내부 프록시를 사용하는 방법을 사용하고, 또 현재 도메인을 이용해 <your-domain>/confluence 와 같이 시용하기 위해 몇가지 설정을 한다. 이를 위해서 nginx 설정 파일, confluence의 server.xml 파일을 수정한다.

/etc/nginx/sites-enabled/default

다음 라인 추가.

         location /confluence {
                client_max_body_size 100m;
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://localhost:8090;
        }

        location /synchrony {
                proxy_set_header X-Forwarded-Host $host;
                proxy_set_header X-Forwarded-Server $host;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_pass http://localhost:8091/synchrony;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
        }

다음 라인 코멘트 처리

    #location = /favicon.ico { log_not_found off; access_log off; }
    #location = /robots.txt { log_not_found off; access_log off; allow all; }
    #location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
    #    expires max;
    #    log_not_found off;
    #}
/opt/atlassian/confluence/conf/server.xml

아래와 같이 수정

    <Connector port="8090" connectionTimeout="20000" redirectPort="8443"
        maxThreads="48" minSpareThreads="10"
        enableLookups="false" acceptCount="10" debug="0" URIEncoding="UTF-8"
        protocol="org.apache.coyote.http11.Http11NioProtocol"
        proxyName="ahnbk.com" proxyPort="443" scheme="https" secure="true" compression="on"/>

...

    <Context path="/confluence" docBase="../confluence" debug="0" reloadable="false" useHttpOnly="true">
                    
...

한글 문제 해결을 위해서, mysql 연결관련 설정에서 링크를 다음과 같이 설정.

jdbc:mysql://localhost:3306/confluence?useUnicode=true&characterEncoding=utf8

위와 같이 수정하고, nginx, confluence 재시작

$ sudo service nginx restart
$ sudo service confluence restart

이제 https://ahnbk.com/confluence 로 접속해보면 (도메인 이름은 각자 상황에 맞게)

와 같이 정상적으로 보인다. ^^ 성공!

Python으로 macOS Text to Speech 엔진 (NSSpeechSynthesizer) 사용해보기

로봇이든 다른 분야에서든 TTS (Text To Speech) 엔진이 필요할 때가 있는데, 보통은 오픈 소스로 공개된 저품질의 엔진이나, 클라우드 엔진을 사용하곤 한다. 물론 요즘 딥러닝 기술이 많이 발전하여 학습 후 실제 목소리와 비슷한 소리를 내는 것도 가능하다곤 하지만, 그건 논외로 하고….

macOS에는 NSSpeechSynthesizer라는 훌륭한 품질의 TTS 엔진 – 그것도 거의 모든 나라의 목소리가 포함되어 있는 – 이 내장되어 있다. 이를 사용하기 위해선 Swift나 ObjectC를 사용할 수도 있지만, 사용하기 쉬운 Python을 이용해서 사용도 가능하다.

먼저 필요한 패키지를 설치한다. 이를 위해 Python3, pip3가 설치되어 있어야 한다. Homebrew (https://docs.brew.sh/Installation)를 이용하면 쉽게 설치 가능하다.

$ pip3 install -U pyobjc

pyobjc 모듈은 Python과 ObjC 간 연결을 위한 것이다. pyobjc는 메타모듈로 이를 설치하면 사용에 필요한 거의 모든 모듈을 다 설치한다.

이제 Python3를 이용하여 다음의 스크립트를 실행해본다.

from AppKit import NSSpeechSynthesizer

speech = NSSpeechSynthesizer.alloc().initWithVoice_("com.apple.speech.synthesis.voice.yuna.premium")
speech.startSpeakingString_(u'안녕? 만나서 반가워요.')

한국어 유나의 목소리로 맑은 음성을 들려줄 것이다. 이외에도 제어를 위한 다양한 함수들이 존재한다.

speech.isSpeaking()
speech.stopSpeaking()

사용 가능한 목소리 리스트를 확인하려면 다음과 같이 입력한다.

>> NSSpeechSynthesizer.availableVoices()

고품질의 목소리를 미리 다운로드 받아야 한다. System Preferences > Accessibility > Speech 에서 System Voice를 선택, Customize 항목으로 들어가면 각 나라별 목소리 리스트와 다운로드 받을 수 있는 체크박스가 존재한다.

끝.

닭볶음탕

닭은 양에 맞는 적당한 크기를 닭볶음탕용으로 준비. (토막토막)

찬물에서 한번 씻고, 넓은 냄비에 넣고, 물은 잠방잠방하게 넣어서 끓인다.

물이 끓기 전, 설탕 or 당분을 취향에 맞게 넣는다.

물이 끓으면, 감자, 당근, 양파를 넣고 끓인다.

야채가 어느 정도 익었다 싶으면, 간마늘 크게 한 수푼 넣고 또 끓인다.

푸욱 끓인 후,

간장 한컵을 넣고

버섯 등 곁들일 야채 추가.

또 끓인 다음, 고추가루를 취향껏 넣는다. 이때 간를 봐서 맞춰야 함. 짜면 물을 보충, 싱거우면 간장 추가.

이제 먹으면 끝!