'일기/스파르타코딩클럽' 카테고리의 글 목록

회사를 퇴사하고 백수로 살던 어느날,

게임만 하고 있던 나 자신에 회의감을 느껴 공부를 어떻게 해야할까 많은 고민을 하고 있었다.

원래 웹퍼블리셔였던 나는 두개의 회사를 거치면서 웹 퍼블리싱과 크게 관련 없는 일을 많이 했는데,

그로 인해 오랜 공백동안 잃어버린 기초와 경력에 맞는 실력을 되찾기 위해 방법을 모색하던 중,

스파르타 코딩 클럽이라는 사이트를 보게 되었다.

 

내일배움단이라고 해서 국비지원으로 내일배움카드를 만들면 실제로 '스파르타코딩클럽'에서 제공하는

강의를 1/10의 가격에 신청하고 수강을 꾸준히 진행해서 수강률 80%를 넘기면 돈도 환급해준다고 하니

반 쯤 혹해서 신청하게 되었는데... (물론 이거는 다른 강의 사이트에서도 진행하는 데가 꽤 있다)

 

2일차 진행상황

 

 

웹개발을 신청한 뒤 하나의 강의를 신청하면 1+1으로 다른 강의를 신청할 수 있다고 해서

나는 앱개발 또한 신청하게 되었다.

그리고 1일차, 하루에 강의가 8개씩 열린다고 해서 초기에는 아는 지식이 많다보니 그냥 쭉쭉 들었다.

총 5주차 과정이지만 우리 내일배움단에서는 2주만에 끝내는게 목표라고 한다. (가능할까?)

평일 오후 2시와 오후 8시에는 게더타운이라고 하는 온라인 스터디방에 접속한 뒤 공부하라고 하는데,

솔직히 아무도 말 안하고 조용할 거 같아서 별 재미가 없을 줄 알았는데, 나름 다른 사람들도 말을 하려고 하는 편이라

들어와서 채팅 혹은 마이크로 대화하면서 강의도 들으니 조금은 괜찮다는 생각이 들었다. (근데 사실 우연히 마이크를 킨거지 그 이후로는 마이크 킨 사람이 없었다...)

시작하면 한 30명정도 모이는 것 같다. 지금 사진은 시간 지나서 다 떠나고 난 뒤 ㅠㅠ.. 이것도 2일차

 

 

2주가 끝나고

마지막 날 치고는 꽤 많은 인원이 모였다.

별로 다들 친하지 않아서 별 얘기 없이 끝났지만 꽤 흥미있게 보낸 것 같다.

 

그리고 실제 오프라인으로 만나서 스터디하는 것보다 공부 의욕이 안 생길줄 알았는데, 그래도 내가 공부를 계속 하고 있는거 보니 (이 글을 쓰는 직전까지 공부하고 있었음) 온라인에서라도 모여서 공부를 하는 것이 효과는 있는거 같다.

사실 게더타운에서 별거 없기 때문에 별 의미없다고 생각해서 따로 공부하시는 분들도 생길거 같긴 하다.

그래도 나는 꽤 맘에 들어서 자주 들어갔다.

 

스온스 얘기는 여기까지 하고, 이제 강의에 대해 얘기해보겟읍니다...

웹개발

웹개발 강의는 왕초보에 딱 적절하고 재미있을 정도로 잘 들어간 것 같다.

0주차에는 개발환경 세팅 및 튜토리얼을 하고,

1주차에는 간단한 HTML, CSS으로 화면 부분을 맛본 뒤에,

2주차에는 여러 도구들을 사용해서 더 쉽게 화면을 구성하고,

3주차에는 파이썬으로 간단한 백엔드를 구성해본다.

4주차에는 백엔드와 프론트를 활용해서 간단한 웹을 이것저것 만들어보고

5주차에는 도메인을 사고, 서버에 도메인을 연결한 뒤에 실제 친구들에게 자랑할 수 있게끔 만든다.

 

진짜 어려운 부분은 크게 안 다루고 쉽게 할 수 있는 난이도인 것 같다.

물론 프로그래밍을 처음 접하는 사람들은 이것도 어려울 순 있겠지만 복습 한두번하면 머리에 담을 수 있는정도...?

난이도도 적절한 데다가 스온스에서 마지막까지 남아 공부하는 사람들을 보면 더 열심히 할 수 있는 원동력이 되는것 같다.

 

나는 예전에 IT학원을 다녔던 적이 있는데 하다가 힘들어서 2주차 3주차가 되면 인원이 80%가량이 빠지던 걸 본 적이 있어서 여기 사람들은 그래도 나름 진심인 것 같다는 생각이 들었다. (물론 더 어려운걸 배우기 시작하면 어떻게 될지는 ㅠㅠ)

나도 기존에 알던 지식 치트(?)로  대부분 쉽게 넘기긴 했지만 새로운 것도 조금 더 배웠고 다음 과목도 배우고 싶다는 생각이 들었다. 하지만 다른 계획이 생겨서 웹개발 플러스는 포기했다.

 

내가 포기한 웹개발 플러스 - 기존 웹개발에서 추가적인 지식을 다룬다

 

앱개발

솔직히 말하면, 엄~청 어렵다. 하지만 꽤 의미있는 강의였다고 생각한다.

 

0주차에는 웹개발과 마찬가지로 튜토리얼을 진행하고,

1주차에는 앱개발에서 사용되는 Javascript 기초를 배운다.

2주차부터 바로 간단한 js 문법들을 재정리하면서 앱을 만들기 시작하는 단계에 온다.

3주차에는 조금 더 한단계 나아간 필수 지식들을 알려주면서 앱을 완성해간다.

4주차에는 웹과 마찬가지로 백엔드에 대해 다룬다. (근데 여기서의 백엔드는 클릭, 클릭으로 쉽게 사용할 수 있어서 웹보다 좀 더 쉬웠던거 같다.)

5주차에는 지금까지 만든 앱에 수익을 내는 법과, 배포 파일을 만들고 스토어에 등록하는 법을 다룬다.

 

시간 비례 나오는 정보의 양이 어마어마하다. (이게 장점이자 단점... 가성비는 좋다 / 근데 내일 배움단으로 하고 있으면 무료니까 가성비가 더 좋다!)

 

나도 두번째 회사에서 개발자로 들어가서 개발은 안하고 교육 컨텐츠를 만들었는데 (이게 불만이어서 나왔다 ㅋㅋㅋ)

그 관점에서 볼 때 이게 사람들 머리에 들어갈까 라는 생각이 문득 들었다. (쉬운것도 이해를 정말 힘들어 하는 사람들이 많다)

1주차부터 강의 2시간가량 되는 분량에 JavaScript의 기초지식을 모두 담고 있는데,

마치 이해를 못하고 넘어갈 것 같은 느낌 이랄까...? (물론 1주차 뒷 영상에 다 이해할 필요 없고 어차피 계속 쓸거여서 이해는 자연스럽게 될 거라는 말이 나오긴 한다)

< 하지만, '앱을 만든다면 이 정도는 해야 되지 않을까'라고 하는 강사님의 말도 틀린말은 없는 것 같다. >

 

일단 이건 다른 듣는 사람들 입장을 물어봐야 알 것 같고, 내 입장에서는 오히려 좋았다.

 

기초 지식이 어느정도 있는 상태에서 하니까, 괜한 불필요한 초반 부분이 짧다는 점이 좋았고

핵심만 콕콕 집어주는 느낌이라서 막막했던 혈이 확 뚫리는 느낌이었다.

2주라는 짧은 시간안에 중요한 핵심들을 엄청 많이 배운 것 같다는 느낌이 들었다.

그리고 가장 중요한 점은 스스로 웹에서 찾아서 코드를 짜는 방법을 강조하면서 강의에서도 웹문서에서 찾아서 직접 적용하는 장면을 많이 보여주는데, 나도 이게 아주 중요하다고 생각 하는데 이런점을 알려주는 건 정말 좋았다.

다만 영상 하나 하나가 30분짜리 영상이 많다 보니 하루 8편씩 진행하면 스온스(게더타운)를 하는 2시간동안에는 절대 못끝낸다는점(물론 꼭 8개씩 진행해야 한다는 규칙은 없지만)은 조금 아쉬웠다.

 

일단 내 입장에서도 앱개발은 모르는 지식들이 실시간으로, 대량으로 쏟아져 나와서 끝난 당장에 기억이 잘 안난다 ㅠㅠ

다만 한번 만들어 봤으니, 복습을 두세번 진행하면 좀 수월하게 할 수 있을 거 같다는 자신감이 생겼다.

 

결과적으로,

나는 스온스 및 내일 배움단이 꽤 괜찮다고 생각을 한다.

무료로 강의를 들을수 있는건 물론이요, 강의를 두개를 준다.

다른 강의들은 모르겠지만 웹개발 만큼은 난이도가 괜찮다 (나같은 초보가 평가하는것도 이상하긴 한데 ㅋㅋㅋ)

완전 처음하는 사람들도 잘 보고 따라한다면 충분히 할 수 있지 않을까 싶다.

다만, 열심히 한다는 전제다.. 스온스은 안나가더라도 막혔을때 슬랙에 질문도 자주 하고,,

이걸 끝낸다고 해서 취업하기에는 부족한 분량이지만 어차피 왕초보(맛보기) 과정이므로 스온스 2주차가 끝난 뒤에 여러가지 과정에 대해 소개해준다. (항해99, 창, 내일배움캠프 등)

 

나는 항해99로 마음을 잡게 되었는데, 그 이유는 다음 포스팅으로 하도록 해보겠다.

물론 이것도 사전 인터뷰 or 면접을 한다고 해서 합격한 다음에 포스팅하도록 하고 떨어진다면 이 부분의 글은 지우겠다 ㅠㅠㅠ (그래도 돈내고 하는 곳이라 지원자가 적으면 잘 뽑히지 않을까? 라는 기대를 해 본다)

 

 

스파르타 코딩 클럽 내일 배움단을 할 사람은 아래의 경우에 권장한다.

1. 내가 개발과 적성이 맞을지 기초를 맛보고 싶은 사람

2. 단기간동안 시간을 갈아서 제대로 입문해볼 사람

3. 혼자서 집에서 공부하려니 뭐부터 해야할지 막막한 사람

 

애초에 코딩이 아니라도 공부란거 자체가 가벼운 마음으로 접하면 죽도 밥도 안된다고 생각한다.

그래서 스파르타 코딩 클럽의 5주 과정을 2주에 끝낸다는 컨셉이 참 좋다고 생각하기도 한다.

(물론 복습은 그 이후에 해도 된다)

 

1번의 경우, 내가 해본 두 과목중에서는 '웹 개발'이 적당한 것 같다.

처음 접하는 사람이 웹이랑 앱 둘다 신청해서 동시에 2주동안 끝내려고 하면 정신이 먼저 갈리지 않을까 생각이 든다.

딱 기초 다지기에도 좋구...

암튼 나 이후에도 할 사람이 있다면 화이팅이다.

스파르타 코딩 클럽 내일 배움단 10일 차 일지

오늘로 스파르타 코딩 클럽 내일 배움단 10일간의 혈투 끝에 웹개발 5주차까지 마무리하게 되었다.

웹개발 기준 분량이 하루에 8편씩 열리는게 2주차에 딱 떨어지게 만들어졌구나 싶다. (나는 주말도 포함해서 10일 했지만 평일 5일씩 2주하면 10일이니)

5주차에는 초반에 간단한 API 복습 이후, 실 서버 세팅에 대한 내용을 다룬다.

지금까지 머리를 싸매는 연속이었는데 이건 명령어도 많지 않고 따라하기만 되서 나름 편하게 넘어갔다.

 

이렇게 앱개발 웹개발 5주차를 마무리 했다.

스파르타 메이킹 챌린지가 언제 시작될지는 모르겠지만 메이킹 챌린지까지 참여할 생각이다.

그 전까지는 공부를 많이 해둬야겠다.

 

학습 내용

1. 무비스타 만들어보기

2. AWS를 이용해 서버 구축하기

3. 쇼핑몰 업로드 해보기

 

1. 무비스타 만들어보기

무비스타 DB 만들기

당장 DB에 데이터가 없으므로 영화배우들의 데이터를 네이버 영화에서 가져오는 파이썬 코드

import requests
from bs4 import BeautifulSoup

from pymongo import MongoClient

client = MongoClient('localhost', 27017)
db = client.dbsparta


# DB에 저장할 영화인들의 출처 url을 가져옵니다.
def get_urls():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get('https://movie.naver.com/movie/sdb/rank/rpeople.nhn', headers=headers)

    soup = BeautifulSoup(data.text, 'html.parser')

    trs = soup.select('#old_content > table > tbody > tr')

    urls = []
    for tr in trs:
        a = tr.select_one('td.title > a')
        if a is not None:
            base_url = 'https://movie.naver.com/'
            url = base_url + a['href']
            urls.append(url)

    return urls


# 출처 url로부터 영화인들의 사진, 이름, 최근작 정보를 가져오고 mystar 콜렉션에 저장합니다.
def insert_star(url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get(url, headers=headers)

    soup = BeautifulSoup(data.text, 'html.parser')

    name = soup.select_one('#content > div.article > div.mv_info_area > div.mv_info.character > h3 > a').text
    img_url = soup.select_one('#content > div.article > div.mv_info_area > div.poster > img')['src']
    recent_work = soup.select_one(
        '#content > div.article > div.mv_info_area > div.mv_info.character > dl > dd > a:nth-child(1)').text

    doc = {
        'name': name,
        'img_url': img_url,
        'recent': recent_work,
        'url': url,
        'like': 0
    }

    db.mystar.insert_one(doc)
    print('완료!', name)


# 기존 mystar 콜렉션을 삭제하고, 출처 url들을 가져온 후, 크롤링하여 DB에 저장합니다.
def insert_all():
    db.mystar.drop()  # mystar 콜렉션을 모두 지워줍니다.
    urls = get_urls()
    for url in urls:
        insert_star(url)


### 실행하기
insert_all()

 

코드 그대로 붙여넣고 실행하면 DB에 데이터가 구성된다.

 

 

무비스타 기본 코드

< app.py >

from pymongo import MongoClient

from flask import Flask, render_template, jsonify, request

app = Flask(__name__)

client = MongoClient('localhost', 27017)
db = client.dbsparta


# HTML 화면 보여주기
@app.route('/')
def home():
    return render_template('index.html')


# API 역할을 하는 부분
@app.route('/api/list', methods=['GET'])
def show_stars():
    sample_receive = request.args.get('sample_give')
    print(sample_receive)
    return jsonify({'msg': 'list 연결되었습니다!'})


@app.route('/api/like', methods=['POST'])
def like_star():
    sample_receive = request.form['sample_give']
    print(sample_receive)
    return jsonify({'msg': 'like 연결되었습니다!'})


@app.route('/api/delete', methods=['POST'])
def delete_star():
    sample_receive = request.form['sample_give']
    print(sample_receive)
    return jsonify({'msg': 'delete 연결되었습니다!'})


if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)

 

< templates/index.html >

<!DOCTYPE html>
<html lang="ko">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>마이 페이보릿 무비스타 | 프론트-백엔드 연결 마지막 예제!</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.8.0/css/bulma.min.css"/>
        <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
        <style>
            .center {
                text-align: center;
            }

            .star-list {
                width: 500px;
                margin: 20px auto 0 auto;
            }

            .star-name {
                display: inline-block;
            }

            .star-name:hover {
                text-decoration: underline;
            }

            .card {
                margin-bottom: 15px;
            }
        </style>
        <script>
            $(document).ready(function () {
                showStar();
            });

            function showStar() {
                $.ajax({
                    type: 'GET',
                    url: '/api/list?sample_give=샘플데이터',
                    data: {},
                    success: function (response) {
                        alert(response['msg']);
                    }
                });
            }

            function likeStar(name) {
                $.ajax({
                    type: 'POST',
                    url: '/api/like',
                    data: {sample_give:'샘플데이터'},
                    success: function (response) {
                        alert(response['msg']);
                    }
                });
            }

            function deleteStar(name) {
                $.ajax({
                    type: 'POST',
                    url: '/api/delete',
                    data: {sample_give:'샘플데이터'},
                    success: function (response) {
                        alert(response['msg']);
                    }
                });
            }

        </script>
    </head>
    <body>
        <section class="hero is-warning">
            <div class="hero-body">
                <div class="container center">
                    <h1 class="title">
                        마이 페이보릿 무비스타😆
                    </h1>
                    <h2 class="subtitle">
                        순위를 매겨봅시다
                    </h2>
                </div>
            </div>
        </section>
        <div class="star-list" id="star-box">
            <div class="card">
                <div class="card-content">
                    <div class="media">
                        <div class="media-left">
                            <figure class="image is-48x48">
                                <img
                                        src="https://search.pstatic.net/common/?src=https%3A%2F%2Fssl.pstatic.net%2Fsstatic%2Fpeople%2Fportrait%2F201807%2F20180731143610623-6213324.jpg&type=u120_150&quality=95"
                                        alt="Placeholder image"
                                />
                            </figure>
                        </div>
                        <div class="media-content">
                            <a href="#" target="_blank" class="star-name title is-4">김다미 (좋아요: 3)</a>
                            <p class="subtitle is-6">안녕, 나의 소울메이트(가제)</p>
                        </div>
                    </div>
                </div>
                <footer class="card-footer">
                    <a href="#" onclick="likeStar('김다미')" class="card-footer-item has-text-info">
                        위로!
                        <span class="icon">
              <i class="fas fa-thumbs-up"></i>
            </span>
                    </a>
                    <a href="#" onclick="deleteStar('김다미')" class="card-footer-item has-text-danger">
                        삭제
                        <span class="icon">
              <i class="fas fa-ban"></i>
            </span>
                    </a>
                </footer>
            </div>
        </div>
    </body>
</html>

 

무비스타 목록 구현하기

< app.js > - show_stars()

@app.route('/api/list', methods=['GET'])
def show_stars():
    movie_star = list(db.mystar.find({}, {'_id': False}).sort('like', -1))
    return jsonify({'movie_stars': movie_star})

 

< templates/index.html > - showStar()

function showStar() {
    $.ajax({
        type: 'GET',
        url: '/api/list?sample_give=샘플데이터',
        data: {},
        success: function (response) {
            let mystars = response['movie_stars']
            for (let i = 0; i < mystars.length; i++) {
                let name = mystars[i]['name']
                let img_url = mystars[i]['img_url']
                let recent = mystars[i]['recent']
                let url = mystars[i]['url']
                let like = mystars[i]['like']

                let temp_html = `<div class="card">
                                    <div class="card-content">
                                        <div class="media">
                                            <div class="media-left">
                                                <figure class="image is-48x48">
                                                    <img
                                                            src="${img_url}"
                                                            alt="Placeholder image"
                                                    />
                                                </figure>
                                            </div>
                                            <div class="media-content">
                                                <a href="${url}" target="_blank" class="star-name title is-4">${name} (좋아요: ${like})</a>
                                                <p class="subtitle is-6">${recent}</p>
                                            </div>
                                        </div>
                                    </div>
                                    <footer class="card-footer">
                                        <a href="#" onclick="likeStar('${name}')" class="card-footer-item has-text-info">
                                            위로!
                                            <span class="icon">
                                  <i class="fas fa-thumbs-up"></i>
                                </span>
                                        </a>
                                        <a href="#" onclick="deleteStar('${name}')" class="card-footer-item has-text-danger">
                                            삭제
                                            <span class="icon">
                                  <i class="fas fa-ban"></i>
                                </span>
                                        </a>
                                    </footer>
                                </div>`
                $('#star-box').append(temp_html)
            }
        }
    });
}

 

 

무비스타 좋아요 구현하기

< app.js > - like_star()

@app.route('/api/like', methods=['POST'])
def like_star():
    name_receive = request.form['name_give']

    target_star = db.mystar.find_one({'name': name_receive})
    current_like = target_star['like']

    new_like = current_like + 1

    db.mystar.update_one({'name': name_receive}, {'$set': {'like': new_like}})

    return jsonify({'msg': '좋아요 완료!'})

 

< app.js > - likeStar()

function likeStar(name) {
    $.ajax({
        type: 'POST',
        url: '/api/like',
        data: {name_give:name},
        success: function (response) {
            alert(response['msg']);
            window.location.reload()
        }
    });
}

 

무비스타 삭제하기 구현하기

< app.js > - delete_star()

@app.route('/api/delete', methods=['POST'])
def delete_star():
    name_receive = request.form['name_give']
    db.mystar.delete_one({'name': name_receive})
    return jsonify({'msg': '삭제 완료!'})

 

< app.js > - deleteStar()

function deleteStar(name) {
      $.ajax({
          type: 'POST',
          url: '/api/delete',
          data: {name_give:name},
          success: function (response) {
              alert(response['msg']);
              window.location.reload()
          }
      });
  }

 

2. AWS를 이용해 서버 구축하기

AWS는 아마존에서 제공해주는 가상서버를 이용할 수 있게 해주는 서비스이다.

회원가입을 하면 무료 서버를 1년 정도 사용할 수 있으며, 1년 사용 이후에는 비용이 추가적으로 청구될 수 있으니

학습 이외 불필요할때는 서버를 종료해주는게 좋다.

 

무료 서버를 구매한 뒤 (무료서버 성능은 기대하지 않는 것이 좋다), SSH를 통해 접속한다.

 

AWS 이용하기

터미널 명령어 입력

ssh -i 받은키페어를끌어다놓기 ubuntu@AWS에적힌내아이피

 

리눅스 명령어 기본

ls: 내 위치의 모든 파일을 보여준다.

pwd: 내 위치(폴더의 경로)를 알려준다.

mkdir: 내 위치 아래에 폴더를 하나 만든다.

cd [갈 곳]: 나를 [갈 곳] 폴더로 이동시킨다.

cd .. : 나를 상위 폴더로 이동시킨다.

cp -r [복사할 것] [붙여넣기 할 것]: 복사 붙여넣기

rm -rf [지울 것]: 지우기

sudo [실행 할 명령어]: 명령어를 관리자 권한으로 실행한다.
sudo su: 관리가 권한으로 들어간다. (나올때는 exit으로 나옴)

 

 

FileZilla 이용하기

아마존에서 얻은 키파일을 사용해서 로그인한다.

 

 

테스트할 파일(test.py)을 루트 디렉토리에 넣은 뒤, 파이썬 파일 테스트

# home 디렉토리로 이동
cd ~

# 실행. 콘솔창에 hellow world!가 뜨는 것을 확인 할 수 있습니다.
python3 test.py

 

파이썬 개발환경 한번에 만들기

아래 파일을 만든 뒤 파일질라로 업로드한다.

< initial_ec2.sh >

# UTC to KST
# 컴퓨터의 시간대를 한국으로
sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime

# python3 -> python
# python3 명령어를 python으로
sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10

# pip3 -> pip
# pip3 설치 및 pip3 명령어를 pip로
sudo apt-get update
sudo apt-get install -y python3-pip
pip3 --version
sudo update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1

# port forwarding
# 포트 포워딩 -> 80 포트로 들어오면 5000포트를 넘겨줌
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 5000

# MongoDB - install
# MongoDB 설치
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
sudo apt-get update
sudo apt-get install -y mongodb-org

sudo mkdir -p /data/db

# MongoDB - run
sudo service mongod start
sleep 7
netstat -tnlp

# MongoDB set user, set conf file
mongo admin --eval 'db.createUser({user: "test", pwd: "test", roles:["root"]});'
sudo sh -c 'echo "security:\n  authorization: enabled" >> /etc/mongod.conf'
sudo sed -i "s,\\(^[[:blank:]]*bindIp:\\) .*,\\1 0.0.0.0," /etc/mongod.conf

# MongoDB 재시작
sudo service mongod stop
sudo service mongod start
sleep 5
netstat -tnlp

 

권한 설정후 실행 (이후, python3 명령어를 python으로 쳐도 됨)

sudo chmod 755 initial_ec2.sh
python test.py

 

FLASK 서버 임시 실행해보기

아래의 샘플 코드로 app.py 파일을 만든 뒤 파일질라로 서버에 업로드 해주기

< app.py >

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is Home!'

if __name__ == '__main__':  
   app.run('0.0.0.0', port=5000, debug=True)

 

ssh로 명령어 입력

# 실행
python app.py

 

pip로 패키지 설치

pip install flask

 

3. 쇼핑몰 업로드 해보기

Robo 3T를 사용해서 AWS MongoDB에 연결해서 DB 잘 뜨는지 확인

 

app.py에서 mongodb 연결 코드 수정

< app.py >

client = MongoClient('mongodb://아이디:비밀번호@localhost', 27017)

 

AWS에서 pymongo설치

# 설치하기
pip install pymongo

 

SSH 접속을 끊어도 서버가 유지되게끔 설정하기 (nohup)

# 아래의 명령어로 실행하면 된다
nohup python app.py &

 

이후, 서버 종료를 하려면? 프로세스를 찾은 뒤 프로세스 번호로 강제종료 시켜줘야 한다

# 아래 명령어로 미리 pid 값(프로세스 번호)을 본다
ps -ef | grep 'app.py'

# 아래 명령어로 특정 프로세스를 죽인다
kill -9 [pid값]

 

 

도메인 구입하기

도메인은 한국 도메인 사이트에서 필요한 것 구하기

가비아 - https://www.gabia.com/

 

웹을 넘어 클라우드로. 가비아

그룹웨어부터 멀티클라우드까지 하나의 클라우드 허브

www.gabia.com

호스팅KR - https://hosting.kr/

 

글로벌 IT 파트너 - 호스팅케이알(HK)

KISA 고객만족도 최다 선정, 도메인 최저가 제공, 기업/공공도메인, 도메인연결/웹호스팅 무료, 서버, 아마존클라우드(AWS), G Suite, 홈페이지제작 1644-7378

www.hosting.kr

 

도메인 호스트 설정 해주기

 

OG 태그로 카카오톡이나 메신저에서 사전정보 표시되게 하기

<meta property="og:title" content="내 사이트의 제목" />
<meta property="og:description" content="보고 있는 페이지의 내용 요약" />
<meta property="og:image" content="{{ url_for('static', filename='ogimage.png') }}" />
 

공유 디버거 - Facebook for Developers

공유 디버거를 사용하면 Facebook에 공유될 때 콘텐츠가 표시되는 모습을 미리 보거나 오픈 그래프 태그를 사용하여 문제를 디버깅할 수 있습니다. 이 도구를 사용하려면 Facebook에 로그인하세요.

developers.facebook.com

 

 

카카오계정 로그인

여기를 눌러 링크를 확인하세요.

accounts.kakao.com

 

 

5주 과정을 갖고 2주간의 길고 긴 학습이 드디어 끝이 났다.

앞으로 한 1~2주간은 지금까지 배운 과정을 복습 하는 기간이 필요할 것 같다.

 

2일 뒤에 웹/앱 5주과정을 모두 듣고 난 후기를 남기도록 하겠다.

스파르타 코딩 클럽 내일 배움단 9일 차 일지

오늘은 일어나서 웹개발 4주 차 강의를 처음부터 쭉 들었다.

웹 개발은 확실히 퍼블리셔 지식이 있다 보니 수월하게 진행하는 게 가능했다.

조금씩은 막히는 부분이 있었긴 했지만 금방 해결하고 다 넘어갔다.

그래서 뭐 적을건 따로 없지만, 파이썬으로 크롤링해서 만드는 부분이 꽤 재밌는 것 같다.

 

학습 내용

1. Flask 기초

2. 모두의 책 리뷰 만들어보기

3. 나홀로 메모장 만들어보기

 

1. Flask 기초

 

Flask란? python을 사용해 손쉽게 웹 백엔드를 구성할 수 있는 프레임워크중 하나 입니다.

파이썬 모듈 설치를 통해 쉽게 설치가 가능합니다.

 

Flask 기본 코드

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'This is Home!'

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

위 코드 입력후, < Ctrl + Shift + F10 > 키를 통해 실행하고, 웹에서 localhost:5000 주소를 입력하여 들어갑니다.

이후, < Ctrl + C > 키를 통해 서버를 종료할 수 있습니다.

 

URL 분리하기

from flask import Flask
app = Flask(__name__)

@app.route('/')
def home():
   return 'Hello'

@app.route('/page')
def mypage():  
   return 'Nice to meet you'

if __name__ == '__main__':  
   app.run('0.0.0.0',port=5000,debug=True)

 

Flask 폴더 구조

프로젝트 폴더

static/

        → *.css

        → *.jpg

templates/

        → *.html

app.py

 

Flask에서 html 로딩하기 ( render_template )

@app.route('/')
def home():
   return render_template('index.html')

 

GET 요청 API 구현 ( Python )

@app.route('/test', methods=['GET'])
def test_get():
   title_receive = request.args.get('title_give')
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 GET!'})

 

GET 요청 AJAX 코드 ( JQuery )

$.ajax({
    type: "GET",
    url: "/test?title_give=봄날은간다",
    data: {},
    success: function(response){
       console.log(response)
    }
})

 

POST 요청 API코드 ( Python )

@app.route('/test', methods=['POST'])
def test_post():
   title_receive = request.form['title_give']
   print(title_receive)
   return jsonify({'result':'success', 'msg': '이 요청은 POST!'})

 

POST 요청 AJAX 코드 ( JQuery )

$.ajax({
    type: "POST",
    url: "/test",
    data: { title_give:'봄날은간다' },
    success: function(response){
       console.log(response)
    }
})

 

 

2. 모두의 책 리뷰

기본코드

< app.py >

from flask import Flask, render_template, jsonify, request
app = Flask(__name__)

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta

## HTML을 주는 부분
@app.route('/')
def home():
    return render_template('index.html')

## API 역할을 하는 부분
@app.route('/review', methods=['POST'])
def write_review():
    sample_receive = request.form['sample_give']
    print(sample_receive)
    return jsonify({'msg': '이 요청은 POST!'})


@app.route('/review', methods=['GET'])
def read_reviews():
    sample_receive = request.args.get('sample_give')
    print(sample_receive)
    return jsonify({'msg': '이 요청은 GET!'})


if __name__ == '__main__':
    app.run('0.0.0.0', port=5000, debug=True)

 

< templates/index.html >

<!DOCTYPE html>
<html lang="ko">

    <head>
        <!-- Webpage Title -->
        <title>모두의 책리뷰 | 스파르타코딩클럽</title>

        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
              integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
              crossorigin="anonymous">

        <!-- JS -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
                integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
                crossorigin="anonymous"></script>

        <!-- 구글폰트 -->
        <link href="https://fonts.googleapis.com/css?family=Do+Hyeon&display=swap" rel="stylesheet">

        <script type="text/javascript">

            $(document).ready(function () {
                showReview();
            });

            function makeReview() {
                $.ajax({
                    type: "POST",
                    url: "/review",
                    data: {sample_give:'샘플데이터'},
                    success: function (response) {
                        alert(response["msg"]);
                        window.location.reload();
                    }
                })
            }

            function showReview() {
                $.ajax({
                    type: "GET",
                    url: "/review?sample_give=샘플데이터",
                    data: {},
                    success: function (response) {
                        alert(response["msg"]);
                    }
                })
            }
        </script>

        <style type="text/css">
            * {
                font-family: "Do Hyeon", sans-serif;
            }

            h1,
            h5 {
                display: inline;
            }

            .info {
                margin-top: 20px;
                margin-bottom: 20px;
            }

            .review {
                text-align: center;
            }

            .reviews {
                margin-top: 100px;
            }
        </style>
    </head>

    <body>
        <div class="container">
            <img src="https://previews.123rf.com/images/maxxyustas/maxxyustas1511/maxxyustas151100002/47858355-education-concept-books-and-textbooks-on-the-bookshelf-3d.jpg"
                 class="img-fluid" alt="Responsive image">
            <div class="info">
                <h1>읽은 책에 대해 말씀해주세요.</h1>
                <p>다른 사람을 위해 리뷰를 남겨주세요! 다 같이 좋은 책을 읽는다면 다 함께 행복해질 수 있지 않을까요?</p>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">제목</span>
                    </div>
                    <input type="text" class="form-control" id="title">
                </div>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">저자</span>
                    </div>
                    <input type="text" class="form-control" id="author">
                </div>
                <div class="input-group mb-3">
                    <div class="input-group-prepend">
                        <span class="input-group-text">리뷰</span>
                    </div>
                    <textarea class="form-control" id="bookReview"
                              cols="30"
                              rows="5" placeholder="140자까지 입력할 수 있습니다."></textarea>
                </div>
                <div class="review">
                    <button onclick="makeReview()" type="button" class="btn btn-primary">리뷰 작성하기</button>
                </div>
            </div>
            <div class="reviews">
                <table class="table">
                    <thead>
                    <tr>
                        <th scope="col">제목</th>
                        <th scope="col">저자</th>
                        <th scope="col">리뷰</th>
                    </tr>
                    </thead>
                    <tbody id="reviews-box">
                    <tr>
                        <td>왕초보 8주 코딩</td>
                        <td>김르탄</td>
                        <td>역시 왕초보 코딩교육의 명가답군요. 따라하다보니 눈 깜짝할 사이에 8주가 지났습니다.</td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </body>

</html>

 

 

모두의책리뷰 - 리뷰 저장

< app.py > - write_review() 수정

## API 역할을 하는 부분
@app.route('/review', methods=['POST'])
def write_review():
    # title_receive로 클라이언트가 준 title 가져오기
    title_receive = request.form['title_give']
    # author_receive로 클라이언트가 준 author 가져오기
    author_receive = request.form['author_give']
    # review_receive로 클라이언트가 준 review 가져오기
    review_receive = request.form['review_give']

    # DB에 삽입할 review 만들기
    doc = {
        'title': title_receive,
        'author': author_receive,
        'review': review_receive
    }
    # reviews에 review 저장하기
    db.bookreview.insert_one(doc)
    # 성공 여부 & 성공 메시지 반환
    return jsonify({'msg': '리뷰가 성공적으로 작성되었습니다.'})

 

< templates/index.html > - makeReview() 수정

function makeReview() {
    // 화면에 입력어 있는 제목, 저자, 리뷰 내용을 가져옵니다.
    let title = $("#title").val();
    let author = $("#author").val();
    let review = $("#bookReview").val();

    // POST /review 에 저장(Create)을 요청합니다.
    $.ajax({
        type: "POST",
        url: "/review",
        data: { title_give: title, author_give: author, review_give: review },
        success: function (response) {
            alert(response["msg"]);
            window.location.reload();
        }
    })
}

 

모두의책리뷰 - 리뷰 보기

< app.py > - read_reviews() 수정

@app.route('/review', methods=['GET'])
def read_reviews():
    # 1. DB에서 리뷰 정보 모두 가져오기
    reviews = list(db.bookreview.find({}, {'_id': False}))
    # 2. 성공 여부 & 리뷰 목록 반환하기
    return jsonify({'all_reviews': reviews})

 

< templates/index.html > - showReview() 수정

function showReview() {
    $.ajax({
        type: "GET",
        url: "/review",
        data: {},
        success: function (response) {
            let reviews = response['all_reviews']
            for (let i = 0; i < reviews.length; i++) {
                let title = reviews[i]['title']
                let author = reviews[i]['author']
                let review = reviews[i]['review']

                let temp_html = `<tr>
                                    <td>${title}</td>
                                    <td>${author}</td>
                                    <td>${review}</td>
                                </tr>`
                $('#reviews-box').append(temp_html)
            }
        }
    })
}

 

2. 나홀로 메모장

meta 태그 스크랩핑

import requests
from bs4 import BeautifulSoup

url = 'https://movie.naver.com/movie/bi/mi/basic.nhn?code=171539'

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
data = requests.get(url,headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

# 여기에 코딩을 해서 meta tag를 먼저 가져와보겠습니다.

og_image = soup.select_one('meta[property="og:image"]')
og_title = soup.select_one('meta[property="og:title"]')
og_description = soup.select_one('meta[property="og:description"]')

url_image = og_image['content']
url_title = og_title['content']
url_description = og_description['content']

print(url_image)
print(url_title)
print(url_description)

 

기본코드

< app.py >

from flask import Flask, render_template, jsonify, request
app = Flask(__name__)

import requests
from bs4 import BeautifulSoup

from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbsparta

## HTML을 주는 부분
@app.route('/')
def home():
   return render_template('index.html')

@app.route('/memo', methods=['GET'])
def listing():
    sample_receive = request.args.get('sample_give')
    print(sample_receive)
    return jsonify({'msg':'GET 연결되었습니다!'})

## API 역할을 하는 부분
@app.route('/memo', methods=['POST'])
def saving():
    sample_receive = request.form['sample_give']
    print(sample_receive)
    return jsonify({'msg':'POST 연결되었습니다!'})

if __name__ == '__main__':
   app.run('0.0.0.0',port=5000,debug=True)

 

< templates/index.html >

<!Doctype html>
<html lang="ko">

    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <!-- Bootstrap CSS -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
              integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
              crossorigin="anonymous">

        <!-- JS -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
                integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
                crossorigin="anonymous"></script>

        <!-- 구글폰트 -->
        <link href="https://fonts.googleapis.com/css?family=Stylish&display=swap" rel="stylesheet">


        <title>스파르타코딩클럽 | 나홀로 메모장</title>

        <!-- style -->
        <style type="text/css">
            * {
                font-family: "Stylish", sans-serif;
            }

            .wrap {
                width: 900px;
                margin: auto;
            }

            .comment {
                color: blue;
                font-weight: bold;
            }

            #post-box {
                width: 500px;
                margin: 20px auto;
                padding: 50px;
                border: black solid;
                border-radius: 5px;
            }
        </style>
        <script>
            $(document).ready(function () {
                showArticles();
            });
            
            function openClose() {
                if ($("#post-box").css("display") == "block") {
                    $("#post-box").hide();
                    $("#btn-post-box").text("포스팅 박스 열기");
                } else {
                    $("#post-box").show();
                    $("#btn-post-box").text("포스팅 박스 닫기");
                }
            }

            function postArticle() {
                $.ajax({
                    type: "POST",
                    url: "/memo",
                    data: {sample_give:'샘플데이터'},
                    success: function (response) { // 성공하면
                        alert(response["msg"]);
                    }
                })
            }

            function showArticles() {
                $.ajax({
                    type: "GET",
                    url: "/memo?sample_give=샘플데이터",
                    data: {},
                    success: function (response) {
                        alert(response["msg"]);
                    }
                })
            }
        </script>

    </head>

    <body>
        <div class="wrap">
            <div class="jumbotron">
                <h1 class="display-4">나홀로 링크 메모장!</h1>
                <p class="lead">중요한 링크를 저장해두고, 나중에 볼 수 있는 공간입니다</p>
                <hr class="my-4">
                <p class="lead">
                    <button onclick="openClose()" id="btn-post-box" type="button" class="btn btn-primary">포스팅 박스 열기
                    </button>
                </p>
            </div>
            <div id="post-box" class="form-post" style="display:none">
                <div>
                    <div class="form-group">
                        <label for="post-url">아티클 URL</label>
                        <input id="post-url" class="form-control" placeholder="">
                    </div>
                    <div class="form-group">
                        <label for="post-comment">간단 코멘트</label>
                        <textarea id="post-comment" class="form-control" rows="2"></textarea>
                    </div>
                    <button type="button" class="btn btn-primary" onclick="postArticle()">기사저장</button>
                </div>
            </div>
            <div id="cards-box" class="card-columns">
                <div class="card">
                    <img class="card-img-top"
                         src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                         alt="Card image cap">
                    <div class="card-body">
                        <a target="_blank" href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                        <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                        <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                    </div>
                </div>
                <div class="card">
                    <img class="card-img-top"
                         src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                         alt="Card image cap">
                    <div class="card-body">
                        <a target="_blank" href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                        <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                        <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                    </div>
                </div>
                <div class="card">
                    <img class="card-img-top"
                         src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                         alt="Card image cap">
                    <div class="card-body">
                        <a target="_blank" href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                        <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                        <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                    </div>
                </div>
                <div class="card">
                    <img class="card-img-top"
                         src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                         alt="Card image cap">
                    <div class="card-body">
                        <a target="_blank" href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                        <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                        <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                    </div>
                </div>
                <div class="card">
                    <img class="card-img-top"
                         src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                         alt="Card image cap">
                    <div class="card-body">
                        <a target="_blank" href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                        <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                        <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                    </div>
                </div>
                <div class="card">
                    <img class="card-img-top"
                         src="https://www.eurail.com/content/dam/images/eurail/Italy%20OCP%20Promo%20Block.adaptive.767.1535627244182.jpg"
                         alt="Card image cap">
                    <div class="card-body">
                        <a target="_blank" href="#" class="card-title">여기 기사 제목이 들어가죠</a>
                        <p class="card-text">기사의 요약 내용이 들어갑니다. 동해물과 백두산이 마르고 닳도록 하느님이 보우하사 우리나라만세 무궁화 삼천리 화려강산...</p>
                        <p class="card-text comment">여기에 코멘트가 들어갑니다.</p>
                    </div>
                </div>
            </div>
        </div>
    </body>

</html>

 

 

메모 저장 구현

< app.py > - saving()

@app.route('/memo', methods=['POST'])
def saving():
    url_receive = request.form['url_give']
    comment_receive = request.form['comment_give']

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get(url_receive, headers=headers)

    soup = BeautifulSoup(data.text, 'html.parser')

    title = soup.select_one('meta[property="og:title"]')['content']
    image = soup.select_one('meta[property="og:image"]')['content']
    desc = soup.select_one('meta[property="og:description"]')['content']

    doc = {
        'title':title,
        'image':image,
        'desc':desc,
        'url':url_receive,
        'comment':comment_receive
    }

    db.articles.insert_one(doc)

    return jsonify({'msg':'저장이 완료되었습니다!'})

 

< templates/index.html > - postArticle()

function postArticle() {
      let url = $('#post-url').val()
      let comment = $('#post-comment').val()

      $.ajax({
          type: "POST",
          url: "/memo",
          data: {url_give:url, comment_give:comment},
          success: function (response) { // 성공하면
              alert(response["msg"]);
              window.location.reload()
          }
      })
  }

 

 

메모 보기 구현

< app.py > - listing()

@app.route('/memo', methods=['GET'])
def listing():
    articles = list(db.articles.find({}, {'_id': False}))
    return jsonify({'all_articles':articles})

 

< templates/index.html > - showArticle()

function showArticles() {
    $.ajax({
        type: "GET",
        url: "/memo",
        data: {},
        success: function (response) {
            let articles = response['all_articles']
            for (let i = 0; i < articles.length; i++) {
                let title = articles[i]['title']
                let image = articles[i]['image']
                let url = articles[i]['url']
                let desc = articles[i]['desc']
                let comment = articles[i]['comment']

                let temp_html = `<div class="card">
                                    <img class="card-img-top"
                                         src="${image}"
                                         alt="Card image cap">
                                    <div class="card-body">
                                        <a target="_blank" href="${url}" class="card-title">${title}</a>
                                        <p class="card-text">${desc}</p>
                                        <p class="card-text comment">${comment}</p>
                                    </div>
                                </div>`
                $('#cards-box').append(temp_html)
            }
        }
    })
}

 

스파르타 코딩 클럽 내일 배움단 9일차 일지

새벽동안에 4주차를 끝내고 일어나서 바로 5주차까지 강의를 보았다.

5주차는 앱광고 등록과 앱스토어에 앱 배포에 대한 내용이라서, 가볍게 보게 되었다.

5주차 영상은 녹화나 필기를 따로 해둔뒤에 나중에 앱하나 개인으로 만들어 보면서 참고해야겠다 라는 생각이 들었다.

웹개발은 아직 코딩강의가 좀 더 남았기에 얼마 남지 않았고 가벼운거만 남은 앱개발 5주차를 빠르게 마무리 했는데,

다하고 든 생각은 '재미있지만 어렵다'이다.

그래서 2주가 끝나려면 아직 조금 더 남았으니 진짜 열심히 복습해야 할 것 같다.

 

학습 내용

1. 광고달기

2. 배포하기

 

1. 광고달기

구글 애드몹 (AdMob)

애드몹이란? 앱 내에 구글 배너광고를 쉽게 붙일수 있도록 해주는 플랫폼? 입니다.

 

애드몹 광고 종류

배너광고, 전면광고, 리워드광고, 네이티브고급광고

 

애드몹 모듈 설치

애드몹 설치 코드

expo install expo-ads-admob

 

+ 애드몹 사이트에서 앱 등록시 나오는 코드를 app.json 하단에 붙여넣어 줍니다.

 

Expo Admob  사용 설명 - https://docs.expo.dev/versions/latest/sdk/admob/

 

Admob - Expo Documentation

Expo is an open-source platform for making universal native apps for Android, iOS, and the web with JavaScript and React.

docs.expo.dev

 

2. 배포하기

로고 이미지와 시작화면 이미지를 만들어 줍니다.

assets/splash.png -> 시작화면 이미지 (앱 시작시 2초~3초 동안 뜨는 화면)

assets/icon.png -> 앱 아이콘 이미지

 

안드앱에서 권한 확보

"android" 부분에 추가합니다.

< app.json >

"permissions": ["ACCESS_FINE_LOCATION", "ACCESS_COARSE_LOCATION"]

 

app.json 공식 문서 - https://docs.expo.dev/versions/latest/config/app/

 

app.json / app.config.js - Expo Documentation

Expo is an open-source platform for making universal native apps for Android, iOS, and the web with JavaScript and React.

docs.expo.dev

 

앱 빌드

expo build:android -t app-bundle

 

 

실 배포는 지금 당장 해볼 수 없는 상황이기에 생략함.

+ Recent posts