自分の分身を作りたい

理系の大学院生だよ

DjangoでHelloWorld出力まで(自分用)

前提

  • Djangoインストール済み
  • Hello Worldくらいまでの話

オンライン教材だと安いけれども、デメリットとして購読をやめたら色々閲覧できなくなるからあとで参照できないですね。

結局本も買って手元に残しておいたほうがいいよね。

Djangoのプロジェクトを作成する

$ django-admin startproject [project name]

$ python manage.py runserver

アプリケーションの機能を作る

$ python manage.py startapp [app name]

viewsの設定

#/yourApp/[app name]/views.py

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse('Hello Django')

ルーティングの設定

プログラムとurlを紐付ける appとprojectそれぞれ設定する

#/yourApp/yourApp/urls.py
from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('[app name]/', include('bbs.urls')),
    path('admin/', admin.site.urls),
]
#/yourApp/[app name]/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

アプリケーションをプロジェクトに登録

INSTALLED_APPS = [
    'bbs.apps.BbsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

アプリケーションの表示をするファイルを作成

  • render()でhtml入るを返すようにする
    #yourApp/[app name]/views.py
    return render(request, 'famima/index.html')
  • アプリディレクトリ直下に/templates/[app name]/index.htmlを作成

CS Dojo Build a startup#1メモ ページ表示まで

f:id:daigakukabuu:20181217224747p:plain

CS Dojoについて

CS Dojo

CS Dojoは元GoogleエンジニアのYKさんがYouTubeで展開しているチャンネル。非常にわかりやすいし、英語の練習にもなります。

Djangoについて

Pythonでwebアプリを作るフレームワーク。Flaskは少し触ったことがあったが、Djangoは初めて触ります。

続きを読む

AmazonのAPIを使ってNode.jsで本のデータを表示する

どうもこんにちは、就活と研究に絶賛挟み撃ち。

 

にも関わらず*1現在趣味で本棚共有アプリを作ってみているわけなのだが、本の表紙イメージを出力させるために、ユーザーにISBNをググって手入力させることを強制させている状態です

*1:就活を通してweb系志望する人たちが何かしら制作物を持っていることを知り、羨ましくなった模様。

続きを読む

技術書共有アプリにユーザーのプロフィールを入力できるようにした。

f:id:daigakukabuu:20181127192156p:plain 

これはPugのファビコンです。可愛いですね。

前回このよううな記事を書きました。

 

www.so-hack.com

 

この中で改良点として考えていた、ユーザープロフィールの編集を実装する

ということをやていこうと思います。

目次

プロフィール編集フォームの実装

まずはじめにプロフィールを編集する時の画面を作成します。

extends layout

block content
    h3.my-3 Edit Profile
    p #{geek.profile}
    form(method="post", action=`/users/${user.userId}?edit=1`)
        div.form-group
            label(for="profile") Your Profile
            textarea(name="profile" rows="4")#profile.form-control
        div.form-group
            button(type="submit").btn.btn-info Save

このアプリではテンプレートエンジンとしてExpressで動作するPugを利用しています。テンプレートエンジンを使うことで効率的にマークアップを行うことができます。

これでプロフィール設定画面にプロフィールを入力するためのテキストエリアとSaveボタンが実装されます。

Getting Started – Pug

コンテンツ部分以外のheadやbodyはすでに作成したlayout.pugにて他のページと共通のものを与えてあります。

doctype html
html
  head
    title= "Share Shelf"
    meta(charset="utf-8")
    meta(http-equiv="X-UA-Compatible" content="IE=edge")
    meta(name="viewport" content="width=device-width, initial-scale=1")
    link(rel='stylesheet', 
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css",
    integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm",
    crossorigin="anonymous")
    link(rel="stylesheet", type="text/css" href="stylesheets/style.css")
  
  body
    nav.navbar.navbar-light.bg-light
      div.navbar-header
        a(href="/").navbar-brand.nav-link Share Shelf
      ul.navbar-nav
        if user
          li.nav-item
            a(href="/logout").nav-link Sign out #{user.username} 
        else
          li.nav-item
            a(href="/login").nav-link Sign in
    div.container
      block content
    footer.fixed-bottom
      div.container
        p.text-muted Please sticky footer content here.
    script(src="/javascripts/bundle.js")

ハンドラをRouterオブジェクトに登録

次にこのページを開くためのハンドラをRouterオブジェクトに登録します。

users.js

//ルーティングを行う
router.get('/:userId/edit', authenticationEnsurer, (req, res, next) => {
    User.findOne({
        where: {
            userId: req.params.userId
        }
    }).then((user) => {
        if (isMine(req, user)) {
            res.render('profile', {
                user: user
            });
        } else {
            const err = new Error('You are not authorized to edit this profile');
            err.status = 404;
            next(err);
        }
    });
});

//ユーザー自身かを確認
function isMine(req, user) {
    return user && parseInt(user.userId) === parseInt(req.user.id);
}

URLからUserIdを拾ってUserデータからそのIdのユーザーを絞り込みそのデータを返します。

UserIdと今ログインしている人のIdを比較して、同じ場合は編集画面を開き、異なる場合はエラーを返すようにしました。

ここまでの段階で読み込んでみると、

f:id:daigakukabuu:20181127174733p:plain

編集画面を開くことができました。

編集を反映させる

次に編集したものを保存して反映できるようにします。

先ほどのusers.jsファイルにPOSTされた時のルーティング処理を追加します。

ユーザーのページを開きつつ、profileを更新しています。

router.post('/:userId', authenticationEnsurer, (req, res, next) => {
    console.log(req.body.profile);
    Book.findAll({
        where: {
            createdBy: req.params.userId
        },
        order: [['"updatedAt"', 'DESC']]
    }).then((books) => {
        if (books) {
            User.findOne({
                where: {
                    userId: req.params.userId
                }
            }).then((user) => {
                if (user && isMine(req, user)) {
                    if (parseInt(req.query.edit) === 1) {
                        user.update({
                            profile: req.body.profile
                        });
                        res.render('user', {
                            books: books,
                            //user: req.user,
                            user: user,
                            geekid: req.params.userId,
                            geek: user
                        });
                    } else {
                        const err = new Error('Bad request');
                        err.status = 400;
                        next(err);
                    }
                } else {
                    const err = new Error('You are not authorized');
                    err.status = 404;
                    next(err);
                }
            });
        console.log(req.params);
        } else {
            const err = new Error('Books not posted');
            err.status = 404;
            next(err);
        }
    });
});

f:id:daigakukabuu:20181127192029p:plain

こんな感じでプロフィールが表示されるようになりました。

ここにその人のやっていることや経歴を書けば、よりその人の本棚が参考になりますね!

グループで技術書を共有するアプリを作ってみた(Node.js)

f:id:daigakukabuu:20181127134014p:plain どうもこんにちは。

最近趣味でプログラミングをやったりしているわけですが、やはりエンジニアとして仕事をしていくとなるとアピールできるようなものを形にしている方が評価される訳です(当たり前)。

そういうこともあり、サーバーサイドもフロントエンドも一通り学んでおかなければなと思い、N予備校のを使ってNode.jsサーバーサイドの勉強ができるコースをやってみた訳です。

そのコースではNode.jsを使って予定調整アプリを作るのですが、すでにそんな機能LINEなんかにあるし完成させるモチベーションが湧かなかったので、もっと欲しいものを作りたいということで、予定調整アプリのチュートリアルを参考にしながらタイトルのようなものを作ってみる事にした。

手っ取り早くコードだけ見る-> GitHub - SoyaManabe/share-shelf

動機

  • 技術書大好き
  • 積ん読になりがち

-> 自分の読んだ本を記録する事でモチベーションと達成感アップ

  • 独学でプログラミングを勉強している
  • 周りのプログラマーがどんな本で勉強しているか知りたい

-> リンクを共有している中でお互いの読んだ本を共有したい

===> 仮想的な本棚で仲間と技術書を共有できるアプリを作りたい

要件定義

  • 読んだ本を投稿できる
  • 仲間が読んだ本を見ることができる
  • 自分が投稿した本の編集、削除
  • 言語技術によって本を絞る
  • メンバーのプロフィール作成や編集

今回はこれらの定義を満たすアプリをExpressというフレームワークを用いて作成しました。

Express - Node.js Web アプリケーション・フレームワーク

tree

.
├── app
├── app.js
├── app.json
├── bin
├── models
├── node_modules
├── package.json
├── package-lock.json
├── public
├── README.md
├── routes
├── test
├── views
└── webpack.config.js

各ディレクトリの中身はGitHubのページで確認できます。

  • app.js アプリを実行した時の起点となるファイル
  • models 作成したデータベースの定義をしているファイルたち
  • public 画像とかスタイルシートとか
  • routes 各ページに移動する時のルーティングをする
  • test 意図通りに動作しているかテストするファイルたち
  • views 各ページのレンダリングファイル(pug)

動作の様子

f:id:daigakukabuu:20181127132748p:plain
ホーム画面、ログイン前は何も見れません

f:id:daigakukabuu:20181127132808p:plain
GitHubアカウントでログインすると共有本棚が見れるようになります

f:id:daigakukabuu:20181127132826p:plain
本をクリックするとその本の詳細を見ることができます

f:id:daigakukabuu:20181127132840p:plain
投稿者であれば詳細の編集が可能

f:id:daigakukabuu:20181127132856p:plain
ユーザーを選択してその人が読んできた本を確認できる

これから改良する点

  • ユーザープロフィールの編集機能を実装する
  • 本の画像をアップするために使うISBNを自動で取得できるようにする(スクレイピングか何かで)

ISBN - Wikipedia

  • クソみたいなUIをなんとかする

この辺りを改善するたびにブログに報告しようと考えています。

Mocha(単体テスト用のNode.jsフレームワーク)メモ

f:id:daigakukabuu:20181116021055p:plain

Mocha

Node.jsのテストフレームワークの中の一つ。

関数の入出力が設計どおりか確かめるためのフレームワークでいわゆる単体テストを行うことができる。

 

↓ドキュメント

Mocha - the fun, simple, flexible JavaScript test framework

 

インストール

パッケージ管理ツールnpmを用いてインストールする。

 

npm install mocha --save-dev

 

--save-devコマンドにより開発する時に利用するライブラリをpackage.jsonに記述しながらインストールできる。

 

使い方

mochaではtest/test.jsファイルがあると自動的にテストを実行してくれる。

であるので、以下のようなtest.jsファイルを作成しよう。

 

$ touch test.js                     //(もしまだなければ)

  

'use strict';
const assert = require('assert');
const dc = require('../');
describe('テスト対象の関数', () => {

 it('要件' () => {
    assert.無名関数
によるテスト処理();
});

it('要件2' () => {
assert.~~~~();
});
.
.


});

 

'テスト対象の関数'のところに記述した関数名がコンソールに出力される。第二引数として無名関数を使い、テスト条件をつらつらと記述してゆく。

 

テスト実行

node_modules/.bin/mocha

 

コンソールに対象の関数名と、各要件ごとのテスト結果が出力される。わーい。

 

Tips

package.jsonにテスト実行コマンドを省略できるように記述しておくと楽かも。

.
.
  "scripts": {
"test": "node_modules/.bin/mocha"
},
.

 

assertでできることについてはこちらを確認しておこう。

Assert | Node.js v11.1.0 Documentation

 

参考

ユニットテストって何?って人向けのmochaとchaiの使い方 - Qiita

 

Vagrant上でのディレクトリを初めてgit pushする

f:id:daigakukabuu:20181109175202p:plainVirtualBox, Vagrant を使った仮想環境で作成したものをGithubにgit pushしようとしたら、

*** Please tell me who you are.

Run

  git config --global user.email "you@example.com"
  git config --global user.name "Your Name"

to set your account's default identity.
Omit --global to set the identity only in this repository.

fatal: empty ident name (for <vagrant@ubuntu-xenial.(none)>) not allowed

名を名乗るのを忘れていたので、指示通りにメールアドレスと名前を登録

$ git config --global user.email "hoge@hoge.com"
$ git config --global user.name "huga"

これでいけるやろと思ってコミットしたら、

Warning: Permanently added 'github.com,192.30.255.112' (RSA) to the list of known h
osts.
Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

ここで気づいた。 いくら1台のパソコン上とはいえ仮想環境上でのUbuntuからアクセスしているので、母艦(mac)とは別口でSSHの設定をしなければならないということに。

そりゃそうだ。

$ ls ~/.ssh
authorized_keys  known_hosts

当然SSH公開鍵を保存しているid_rsa.pubはなかったので

$ ssh-keygen -t rsa -C "hoge@hoge.com"

作成されたid_rsa.pubをvimで開いてコピー。

Githubの右上の自分のアイコンからSettingsを開いて

'SSH and GPG keys'ページを開いて'New SSH key'を選択。

先ほどコピーしたSSH公開鍵をペースト。

これで完了。

まとめ

  • vagrantで仮想環境を立ち上げる=別のパソコンを立ち上げる
  • つまりSSH公開鍵を新たに作成しないとダメよ
  • 同じ過ちは繰り返さないようにしよう

参考

monsat.hatenablog.com

jsapachehtml.hatenablog.com