見出し画像

レンタルサーバでWebアプリ作り: 総仕上げ = GPTeacher

ロリポップレンタルサーバではできることが限られていたので、ホスティングサービスの DigitalOcean を使ってWebアプリを公開するまでの道のりを記録します。

以下は DigitalOcean の紹介リンクですが、ここから手続きを進めてもらえると200ドル分の無料チケット(有効期間2ヶ月)がもらえるようですので、ぜひご活用ください。(2024/1/2時点)

https://m.do.co/c/a8b31ed34b75


背景

前回までで、Socket通信の実装・ChatGPTのテケテケ表示・複数ページの切り分け・画面デザインなどを積み重ねて、アプリを作る土台が出来上がりました。それを組み合わせて、最終ゴールである「Webアプリ構築」を目指します!


ゴール=歌詞作りアプリを作る!

題材は、「歌詞生成」。先日ちょっと脱線して新年ソングを作りました。

歌詞生成はChatGPTを使ったのですが、それをアプリ化します。一発目のアプリなんでシンプルにしようと思い、これを題材にしました。
名付けて、Lyrics Maker !

結果サイト(出来上がったサイト)


フォルダ構成

最終的には複数アプリを搭載予定なので(野望は高く♪)、その1つのアプリとして作っていきます。
「GPTeacher」というサイトを作り、その中に「lyricsmaker」があるといGPう構成です。
※ GP = Great Pioneer (例のGPTのGPではありません♪)

ということで、最終的に以下のようなフォルダ構成になりました。ちなみに、最後の「folder_and_file_checker.py」は、このフォルダ構成を出力するためのもので、Webアプリ作りには不要です。

GPTeacher \ 
 ├── app \ 
 │   ├── common \ 
 │   ├── LyricsMaker \ 
 │   │   ├── templates \ 
 │   │   │   └── index.html
 │   │   ├── LyricsMaker.py
 │   │   └── __init__.py
 │   ├── static \ 
 │   │   ├── css \ 
 │   │   │   └── style.css
 │   │   ├── img \ 
 │   │   │   ├── logo.png
 │   │   │   └── title.png
 │   │   ├── js \ 
 │   ├── TopPage \ 
 │   │   ├── templates \ 
 │   │   │   ├── folder_and_file_checker.py
 │   │   │   └── toppage.html
 │   │   ├── TopPage.py
 │   │   └── __init__.py
 │   ├── myopenai.py
 │   ├── socket_config.py
 │   └── __init__.py
 ├── .env
 ├── gunicorn_config.py
 ├── Pipfile
 ├── Pipfile.lock
 ├── Procfile
 ├── requirements.txt
 └── run.py
 └── folder_and_file_checker.py

過去の記事( https://note.com/cryptoscore/n/n5346dcdcdd0d )で、なぜ上記のようなフォルダ構成にしているかを解説しています。

ファイル説明

大部分は過去の記事にまとめたものを駆使して作っているので、詳しくはそちらをご覧いただければと思いますが、今回アプリ化する際に追加したものを抜きだして説明します。

CSSファイルの切り分け
CSSが大きくなったので、static/css/style.css に切り出しました。
切り出しは結構簡単で、HTMLの<style>の中身をマルっとコピーすればOKです。以下のような感じ。

body {
    font-family: Arial, sans-serif;
    background-color: #031620; /* ダークブルーの背景色 */
    color: #8892B0; /* ソフトなブルーグレーのテキスト色 */
    margin: 0;
    padding: 0;
}

で、HTMLにどう書くかがポイントで、以下のように書きます。

<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/style.css') }}">

ポイントは、「Lyrincアプリの外側にある共通フォルダ(static)にあるCSSを使う」という点で、そんな場合は url_for を使います。

ロゴ画像の挿入
GPT先生にロゴ画像を作ってもらい、それをHTMLに読み込むのですが、その際のパス指定もCSSと同じ要領です。

<img src="{{ url_for('static', filename='img/title.png') }}">


”少々お待ちください”の表示
歌詞作成ボタンを押したら、GPTから回答が返ってくるまで「少々お待ちください」というよく見る画面を出すようにしました。

まずHTMLの<body>内に、以下のように表示物を置きます。

            <!-- 少々お待ちください の画面 -->
            <div id="overlay">
                <div id="spinner"></div>
                <div id="text">少々お待ちください</div>
            </div>

そして、<script>にあるボタン機能のところに以下の一文=少々お待ちくださいを表示する一文を入れます。

document.getElementById('overlay').style.display = 'block';

また、GPTから終了サインが送られたら以下の一文が動くようにします。これで、少々お待ちください画面が消えるようになります。

document.getElementById('overlay').style.display = 'none';

最後に、これのレイアウトをCSS内に書き入れます。

#overlay {
    display: none;
    position: fixed;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0,0,0,0.5);
    z-index: 2;
    cursor: pointer;
}

#text {
    position: absolute;
    top: 50%;
    left: 50%;
    font-size: 20px;
    color: white;
    transform: translate(-50%,-50%);
}
#spinner {
    border: 6px solid rgba(0, 0, 0, 0.1);
    border-radius: 50%;
    border-top: 6px solid #3498db;
    width: 60px;
    height: 60px;
    animation: spin 2s linear infinite;
    position: absolute;
    top: 40%;
    left: 50%;
    transform: translate(-50%, -50%);
}
@keyframes spin {
    0% { transform: translate(-50%, -50%) rotate(0deg); }
    100% { transform: translate(-50%, -50%) rotate(360deg); }
}

こんな感じで、GPTが考えている間「少々お待ちください」が出るようになります。

クリップボードにコピー
もう一つ、GPTが出力した歌詞部分をクリップボードにコピーする機能も設けました。

<div class="copyarea-container">
    <div class="copy_btn" onclick="copyText()">COPY</div>
    <div class="copy_area" id="log"></div>
</div>

copyText()は、以下のような内容です。

        function copyText() {
            var text = document.getElementById('log').innerText;
            var textarea = document.createElement('textarea');
            textarea.value = text;
            document.body.appendChild(textarea);
            textarea.select();
            document.execCommand('copy');
            document.body.removeChild(textarea);
        }

CSSは以下のような内容です。

.copyarea-container {
    border: 2px solid #000;
    padding: 20px;
    position: relative;
}

.copy_area {
    margin-top: 20px;
    border: 1px solid #000;
    padding: 10px;
    color: white;
}

.copy_btn {
    position: absolute;
    top: 10px;
    right: 10px;
    font-size: 10px;
    cursor: pointer;
}


あとは過去の記事にまとめたようなことを駆使して、以下のようなサイトが完成しました!


最後までご覧いただきありがとうございました!

正月休みがすべてこれに浪費されましたが、完成したので大満足 ♪
皆様のご参考になれば幸いです!

この記事/マガジンがご参考になり、「支援してもいいよ~」と思っていただいた方は、ぜひ有料記事としてご購入いただければ幸いです。
(有料記事部分で、フォルダチェッカーも含めたプログラムの全部を公開しております)

ここから先は

2,114字 / 1ファイル

¥ 980

この記事が気に入ったらサポートをしてみませんか?