Sponsored By
















※ 본 포스팅은 lourcode 님의 글을 참고하였습니다.(원본링크 : [https://lourcode.kr/posts/Jekyll-기반-Github-Pages와-Notion-Page-연동/](https://lourcode.kr/posts/Jekyll-%EA%B8%B0%EB%B0%98-Github-Pages%EC%99%80-Notion-Page-%EC%97%B0%EB%8F%99/))



### 1. API 키 설정


   1-1. 아래 주소 클릭
https://www.notion.so/my-integrations


   1-2. 새 API 통합 클릭






   1-3. 연결된 워크스페이스를 확인하고 이름을 만들어주고 '제출' 버튼 클릭






   1-4. 시크릿키가 생성되면 표시 → 복사 를 순서대로 클릭하여 키값을 복사한다.






※ 시크릿키값은 secret_* 의 형태로 되어있다.


 



## 2. 노션에서 사용/연동 할 데이터베이스 생성


   2-1. 아래와 같이 샘플용으로 만들어본다.(공유링크 : https://asteriskos.notion.site/Blog-DB-85109cf911b74a62a5041f6047d5792d?pvs=4)




   2-2. 테이블에 마우스를 가져가 되면 옆에 더보기(::)가 표시되는데 클릭한다.






   2-3. 링크복사를 누른다
https://www.notion.so/asteriskos/de2dcf74aff44030954dbd4d991c559b?v=1f7e542c866341c1a8d68c9c328c3faf&pvs=4


굵게 표시한 부분이 데이터베이스의 ID 이다. 기억해둔다.



## 3. 데이터베이스 페이지에 API연동


   3-1. 데이터베이스 생성한 페이지 우측상단에  더보기(…) 를 클릭하여 API를 연동한다.






   3-2. 연결할거냐는 팝업이뜨는데, '확인' 버튼을 눌러 연결됨을 확인하자.

 









## 4. 깃허브 파일 설정


   4-1. Settings → Secrets and variables → Actions 를 눌러 키를 생성해야한다.
       4-1-1. '1-4' 에서 확보한 노션토큰을 'NOTION_TOKEN'으로 저장한다.
       4-1-2. '2-3' 에서 확보한 DB ID를 'DATABASE_ID' 로 저장한다.       
       4-1-2. '깃허브 personalKey'를 'GH_TOKEN' 으로 저장한다. 




   4-2. root 폴더에 ‘_scripts’ 폴더를 생성하고, 생성한 폴더 안에 ‘**notion-import.js**’ 파일을 만들고 아래 내용을 입력한다.

const { Client } = require("@notionhq/client");
const { NotionToMarkdown } = require("notion-to-md");
const moment = require("moment");
const path = require("path");
const fs = require("fs");
const axios = require("axios");

const notion = new Client({
  auth: process.env.NOTION_TOKEN,
});

function escapeCodeBlock(body) {
  const regex = /```([\s\S]*?)```/g
  return body.replace(regex, function (match, htmlBlock) {
    return "{% raw %}\n```\n" + htmlBlock + "\n```\n{% endraw %}";
  })
}

function replaceTitleOutsideRawBlocks(body) {
  const rawBlocks = [];
  const placeholder = "%%RAW_BLOCK%%";
  body = body.replace(/{% raw %}[\s\S]*?{% endraw %}/g, (match) => {
    rawBlocks.push(match);
    return placeholder;
  });

  const regex = /\n#[^\n]+\n/g;
  body = body.replace(regex, function (match) {
    return "\n" + match.replace("\n#", "\n##");
  });

  rawBlocks.forEach(block => {
    body = body.replace(placeholder, block);
  });

  return body;
}

// passing notion client to the option
const n2m = new NotionToMarkdown({ notionClient: notion });

(async () => {
  // ensure directory exists
  const root = "_posts";
  fs.mkdirSync(root, { recursive: true });

  const databaseId = process.env.DATABASE_ID;
  let response = await notion.databases.query({
    database_id: databaseId,
    filter: {
      property: "배포",
      checkbox: {
        equals: true,
      },
    },
  });

  const pages = response.results;
  while (response.has_more) {
    const nextCursor = response.next_cursor;
    response = await notion.databases.query({
      database_id: databaseId,
      start_cursor: nextCursor,
      filter: {
        property: "배포",
        checkbox: {
          equals: true,
        },
      },
    });
    pages.push(...response.results);
  }

  for (const r of pages) {
    const id = r.id;
    // date
    let date = moment(r.created_time).format("YYYY-MM-DD");
    let pdate = r.properties?.["날짜"]?.["date"]?.["start"];
    if (pdate) {
      date = moment(pdate).format("YYYY-MM-DD");
    }
    // title
    let title = id;
    let ptitle = r.properties?.["게시물"]?.["title"];
    if (ptitle?.length > 0) {
      title = ptitle[0]?.["plain_text"];
    }
    // tags
    let tags = [];
    let ptags = r.properties?.["태그"]?.["multi_select"];
    for (const t of ptags) {
      const n = t?.["name"];
      if (n) {
        tags.push(n);
      }
    }
    // categories
    let cats = [];
    let pcats = r.properties?.["카테고리"]?.["multi_select"];
    for (const t of pcats) {
      const n = t?.["name"];
      if (n) {
        cats.push(n);
      }
    } 
    // frontmatter
    let fmtags = "";
    let fmcats = "";
    let fmassrtmnt = "";
    if (tags.length > 0) {
      fmtags += "[";
      for (const t of tags) {
        fmtags += t + ", ";
      }
      fmtags += "]";
    }

    if (assrtmnt.length > 0) {
      fmassrtmnt += "[";
      for (const t of assrtmnt) {
        fmassrtmnt += t ;
      }
      fmassrtmnt += "]";
    }
    const fm = `---
title: "${title}"
excerpt: ""
header: ""

categories:
    - ${fmcats}
tags:
    - ${fmtags}
last_modified_at: ${date}
---
<br><br>
`;
    const mdblocks = await n2m.pageToMarkdown(id);
    let body = n2m.toMarkdownString(mdblocks)["parent"];
    if (body === "") {
      continue;
    }
    body = escapeCodeBlock(body);
    body = replaceTitleOutsideRawBlocks(body);

    const ftitle = `${date}-${title.replaceAll(" ", "_")}.md`;

    let index = 0;
    let edited_md = body.replace(
      /!\[(.*?)\]\((.*?)\)/g,
      function (match, p1, p2, p3) {
        // const dirname = path.join("assets/img", ftitle);
        const dirname = path.join("upload", ftitle);
        if (!fs.existsSync(dirname)) {
          fs.mkdirSync(dirname, { recursive: true });
        }
        const filename = path.join(dirname, `${index}.png`);

        axios({
          method: "get",
          url: p2,
          responseType: "stream",
        })
          .then(function (response) {
            let file = fs.createWriteStream(`${filename}`);
            response.data.pipe(file);
          })
          .catch(function (error) {
            console.log(error);
          });

        let res;
        if (p1 === "") res = "";
        else res = `_${p1}_`;

        return `![${index++}](/${filename})${res}`;
      }
    );

    //writing to file
    fs.writeFile(path.join(root, ftitle), fm + edited_md, (err) => {
      if (err) {
        console.log(err);
      }
    });
  }
})();





   4-3. 위 JavaScript 파일(**notion-import.js**)에 대한 dependencies 설정을 위해 'package.json' 파일 하단에 아래 내용을 입력 해 준다.

## yaml

name: "Build and Deploy"
on:
  repository_dispatch:
    types: [RUN_WORKFLOW_DISPATCH]
      
permissions:
  contents: write
  pages: write
  id-token: write

# Allow one concurrent deployment
concurrency:
  group: "pages"
  cancel-in-progress: true

jobs:
  importer:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@master      
      - uses: actions/setup-node@v3
        with:
          node-version: "17"

      - run: npm install

      - run: node _scripts/notion-import.js
        env:
          NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
          DATABASE_ID: ${{ secrets.DATABASE_ID }}

      - uses: stefanzweifel/git-auto-commit-action@v4
        env:
          GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
        with:
          commit_message: "[BOT] Commit & Deploy from Notion"
          branch: main
          commit_user_name: morimin-bot 🤖
          commit_user_email: morimin@github.com
          commit_author: morimin-bot 🤖 <morimin@github.com>
 
  build:
    needs: importer
    runs-on: ubuntu-latest

    steps:           
      - name: Checkout
        uses: actions/checkout@v3
        with:
          ref: main
          fetch-depth: 1

      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v1

      - name: Setup Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: '3.1' # reads from a '.ruby-version' or '.tools-version' file if 'ruby-version' is omitted
          bundler-cache: true

      - name: Build site
        run: bundle exec jekyll b -d "_site${{ steps.pages.outputs.base_path }}"
        env:
          JEKYLL_ENV: "production"

      - name: Test site
        run: |
          bundle exec htmlproofer _site --disable-external --check-html --allow_hash_href

      - name: Upload site artifact
        uses: actions/upload-pages-artifact@v1
        with:
          path: "_site${{ steps.pages.outputs.base_path }}"

  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1




   4-4. root 폴더에 ‘.github’ 폴더를 생성하고, 생성한 폴더 안에 ‘workflows’ 폴더를 생성하고, 생성한 폴더 안에 ‘pages-deploy.yml’ 파일을 만들고 아래 내용을 입력한다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    .trigger-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center;
    }

    .trigger-button {
      display: inline-block;
      margin-bottom: 10px;
      padding: 10px 20px;
      background-color: #4c9aff;
      color: white;
      font-size: 16px;
      border: none;
      cursor: pointer;
      border-radius: 4px;
      box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
      transition: background-color 0.3s;
    }

    .trigger-button:hover {
      background-color: #2e86ff;
    }

    .message {
      font-size: 16px;
      color: #333;
    }
  </style>
</head>
<body>
  <div class="trigger-container">
    <button id="triggerButton" class="trigger-button">UPLOAD</button>
    <div id="message" class="message"></div>
  </div>

  <script>
  document.getElementById("triggerButton").addEventListener("click", function() {
    var messageElement = document.getElementById("message");
    messageElement.textContent = "요청 전송 중...";

    var xhr = new XMLHttpRequest();
    xhr.open("POST", "https://api.github.com/repos/USERNAME/REPO_NAME/dispatches", true);
    xhr.setRequestHeader("Accept", "application/vnd.github.v3+json");
    xhr.setRequestHeader("Authorization", "Bearer GITHUB_ACCESS_TOKEN");
    xhr.setRequestHeader("Content-Type", "application/json");

    xhr.onload = function() {
      if (xhr.status === 204) {
        messageElement.textContent = "요청이 성공적으로 전송되었습니다." + xhr.status;
      } else {
        messageElement.textContent = "요청 전송에 실패했습니다.<br>상태 코드: " + xhr.status;
      }
    };

    xhr.onerror = function() {
      messageElement.textContent = "요청 전송 중 알 수 없는 오류가 발생했습니다.";
    };

    xhr.send(JSON.stringify({"event_type": "RUN_WORKFLOW_DISPATCH"}));
  });
</script>
</body>
</html>





   4-5. 배포버튼을 만들기 위해, 아래 링크 중 본인의 내용에 맞게 수정(아래 하이라이트 부분)한다.

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    .trigger-container {
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center;
    }

    .trigger-button {
      display: inline-block;
      margin-bottom: 10px;
      padding: 10px 20px;
      background-color: #4c9aff;
      color: white;
      font-size: 16px;
      border: none;
      cursor: pointer;
      border-radius: 4px;
      box-shadow: 0px 2px 6px rgba(0, 0, 0, 0.1);
      transition: background-color 0.3s;
    }

    .trigger-button:hover {
      background-color: #2e86ff;
    }

    .message {
      font-size: 16px;
      color: #333;
    }
  </style>
</head>
<body>
  <div class="trigger-container">
    <button id="triggerButton" class="trigger-button">UPLOAD</button>
    <div id="message" class="message"></div>
  </div>

  <script>
  document.getElementById("triggerButton").addEventListener("click", function() {
    var messageElement = document.getElementById("message");
    messageElement.textContent = "요청 전송 중...";

    var xhr = new XMLHttpRequest();
    xhr.open("POST", "https://api.github.com/repos/USERNAME/REPO_NAME/dispatches", true);
    xhr.setRequestHeader("Accept", "application/vnd.github.v3+json");
    xhr.setRequestHeader("Authorization", "Bearer GITHUB_ACCESS_TOKEN");
    xhr.setRequestHeader("Content-Type", "application/json");

    xhr.onload = function() {
      if (xhr.status === 204) {
        messageElement.textContent = "요청이 성공적으로 전송되었습니다." + xhr.status;
      } else {
        messageElement.textContent = "요청 전송에 실패했습니다.<br>상태 코드: " + xhr.status;
      }
    };

    xhr.onerror = function() {
      messageElement.textContent = "요청 전송 중 알 수 없는 오류가 발생했습니다.";
    };

    xhr.send(JSON.stringify({"event_type": "RUN_WORKFLOW_DISPATCH"}));
  });
</script>
</body>
</html>






   4-6. 배포 버튼을 링크로 만들기 위해 아래HTML블록생성 링크로 접속한다.
https://www.notion-tools.com/embeds/html






   4-7. 위 ‘4-5’에서 만든 코드를 넣고 링크를 생성한다.






   4-8. 노션에서 /embed 를 검색해서 임베드 블록을 생성한다.






   4-9. 위 ‘4-7’에서 생성한 링크를 임베드 해준다.






   4-10. 생성된 배포 버튼(임베디드된 링크)






   4-11. 업로드 버튼을 눌르면, 깃액션을 통해 봇으로 배포되는 것을 확인할 수 있다.









### 1. data 폴더로 들어간다.

cd /data





### 2. 명령어(du -ch)를 입력하여 디비 스키마별 용량을 확인하자.

du -ch

※ permission denied 가 뜨면 다음 명령어로 실행
sudo du -ch



ㅁ 결과 : 




## 1. 노션 API 등록/설정


1-1. 아래 주소 클릭
https://www.notion.so/my-integrations


1-2. 새 API 통합 클릭




1-3. 연결된 워크스페이스를 확인하고 이름을 만들어주고 ‘제출’ 버튼 클릭






1-4. 시크릿키가 생성되면 표시 > 복사 를 순서대로 클릭하여 키값을 복사한다.






※ 시크릿키값은 secret_* 의 형태로 되어있다.


 



## 2. 노션에서 사용/연동 할 데이터베이스 생성


2-1. 아래와 같이 샘플용으로 만들어본다.





2-2. 테이블에 마우스를 가져가 되면 옆에 더보기(::)가 표시되는데 클릭한다.


2-3. 링크복사를 누른다
https://www.notion.so/asteriskos/de2dcf74aff44030954dbd4d991c559b?v=1f7e542c866341c1a8d68c9c328c3faf&pvs=4

표시한 부분이 데이터베이스의 ID 이다. 



## 3. 데이터베이스 페이지에 API연동


3-1. 데이터베이스 생성한 페이지 우측상단에  더보기(…) 를 클릭하여 API를 연동한다.






3-2. 연결할거냐는 팝업이뜨는데, ‘확인’ 버튼을 눌러 연결됨을 확인하자.






## 4. 파이썬 코딩하여 노션 데이터베이스에 데이터 넣기


4-1. 데이터베이스 페이지 가져오기

import requests, json

def readDatabase(databaseId, token):
    
    readUrl = f"https://api.notion.com/v1/databases/{databaseId}/query"
headers = {'Content-Type': 'application/json', "Authorization": 'Bearer ' + token, "Notion-Version": '2022-06-28'}
    res = requests.post(readUrl, headers=headers)
    data = res.json()
 
    if res.status_code == 200:
        for result in data['results']:
            try:
                properties = result['properties']
col1 = properties['Name']['title'][0]['text']['content']
                col2 = properties['금액']['number']
                print(f'Name: {col1}, 금액: {col2}')
            except:
                continue
        
token = "{Your Private API Token}"

databaseId = "{Your DatabaseID}"

readDatabase(databaseId=databaseId, token=token)




4-2. 적용>실행 후 데이터 불러온 값 확인하기(결과)






4-3. 노션 데이터베이스에 페이지 추가하기

import requests, json


def InsertData(databaseId, token, dataArray):
    createdUrl = "https://api.notion.com/v1/pages"
    headers = {'Content-Type': 'application/json', "Authorization": 'Bearer ' + token, "Notion-Version": '2022-06-28'}

    data = {
        "parent": {"database_id": databaseId},
        "properties": {
            "Name": {
                "title": [
                    {
                        "text": {
                            "content": dataArray['Name']
                        }
                    }
                ]
            },
            "금액": {
                "number": dataArray['금액']
            }
        }
    }

    data = json.dumps(data)
    res = requests.post(createdUrl, headers=headers, data=data)
    if res.status_code == 200:
    print('## 정상입력 ##')
  else:
    print('## 입력에러 ##')   


token = "{Your Private API Token}"

databaseId = "{Your DatabaseID}"


dataArray = {
    'Name': 'Test_789',
    '금액': 123333
}

InsertData(databaseId=databaseId, token=token, dataArray=dataArray)




4-4. 결과 






1․ 인공지능(AI) 및 기계 학습
AI와 기계 학습은 IT 분야에서 가장 흥미로운 기술 중 두 가지로, 컴퓨터가 학습하고 적응할 수 있게 만들어
이미지 인식, 음성 인식 및 자연어 처리 등의 작업에서 더 나은 결과를 보이도록 합니다. AI와 기계 학습은 챗봇
및 가상 어시스턴트부터 자율 주행 자동차 및 맞춤형 의학에 이르기까지 다양한 분야에서 사용됩니다.



2․ 클라우드 컴퓨팅
클라우드 컴퓨팅은 오래전부터 존재하지만, IT 분야에서 주요 트렌드 중 하나로 지속됩니다. 클라우드 컴퓨팅은
비즈니스 및 개인이 로컬 서버 또는 컴퓨터 대신 인터넷을 통해 데이터 및 애플리케이션에 액세스하고 저장할 수
있도록 합니다. 이를 통해 필요에 따라 확장하거나 축소하고 어디서든 컴퓨팅 자원에 액세스하는 것이 더 쉽고 비용
효율적으로 가능합니다.



3․ 사물 인터넷(IoT)
사물 인터넷(IoT)은 센서와 소프트웨어가 내장된 물리적 장치, 차량 및 기타 개체의 상호 연결된 네트워크를
의미합니다. IoT는 스마트 홈 및 웨어러블 기술부터 산업 자동화 및 의료에 이르기까지 다양한 분야에서 사용되고
있습니다.



4․ 사이버 보안
데이터 및 애플리케이션의 대부분이 클라우드로 이동하고 연결된 장치 및 시스템의 수가 계속해서 증가함에 따라,
사이버 보안은 비즈니스 및 개인 모두에게 중요한 문제가 되고 있습니다. 사이버 보안 기술 및 관행은 점점 더
복잡하고 효과적으로 발전하여 사이버 공격으로부터 보호하는 데 있어 더욱 세련되고 효과적인 방법을 제공하고
있습니다.



5․ 블록체인
블록체인은 비트코인에서 시작되었지만, 현재는 다양한 산업에서 사용되는 중요한 기술입니다. 블록체인은 분산 원장
기술로, 각 블록에는 고유한 해시가 포함되어 있어 블록 간의 변조가 어렵습니다. 이러한 특징을 통해 데이터 보안과
무결성을 보장할 수 있습니다.

블록체인은 은행 및 금융 업계에서 금융 거래에 사용되는 데, 더 나아가 의료, 공공 서비스, 부동산 등의
분야에서도 사용됩니다. 블록체인 기술은 더욱 안전하고 효율적인 거래를 가능케 하며, 이를 통해 비용 절감과 고객
만족도 향상 등 다양한 이점을 제공합니다.



6․ 5G
5G는 현재 IT 분야에서 가장 핫한 토픽 중 하나입니다. 5G는 이전의 모바일 네트워크보다 훨씬 빠르고 안정적인
연결을 제공합니다. 이를 통해 더 높은 대역폭, 더 빠른 다운로드 및 업로드 속도, 그리고 다양한 새로운 기능과
서비스가 가능해집니다.

 

 


7․ 가상 현실(VR) 및 증강 현실(AR)
가상 현실(VR) 및 증강 현실(AR)은 지난 몇 년간 크게 발전해 왔습니다. VR과 AR 기술은 게임, 교육, 의료,
건축 등의 분야에서 사용됩니다. 이러한 기술은 새로운 경험과 시각적 효과를 제공하며, 다양한 새로운 시장 기회를
만들어 냅니다.



8․ 로봇 공학 및 자율 주행 기술
로봇 공학 및 자율 주행 기술은 미래의 세상을 변화시킬 수 있는 중요한 기술 중 하나입니다. 로봇은 제조 및 물류
분야에서 사용되는 데 반해, 자율 주행 차량은 교통 분야에서 주로 사용됩니다. 이러한 기술은 생산성을 높이고
안전성을 향상시키는 등 다양한 이점을 제공합니다.


※ 출처 : https://asterisco.tistory.com/527



응용시스템(Application Systems)에 대한 위협모델 별 대응 방안은 아래와 같다:<br>

 

위협 대응(통제)
스푸핑 (Spoofing) ID, PW 설정
데이터 조작 (Tampering) HASH 값 확인(설정)
거부 (Repudiation) 디지털 서명 설정
정보노출 (Information Disclosure) 암호화
서비스 거부 (Denial of Services, DOS) 네트워크 필터링(Anomaly IDS 등)
권한 상승 (Elevation Of Privilege ) 사용자 권한 통제 및 SOD



 



Sponsored By















+ Recent posts