본문 바로가기
Programming/Python

카카오톡 플러스친구 스마트채팅 만들기 4 - 식당 목록 전달

by NAMP 2018. 5. 6.

카카오톡 플러스친구 스마트채팅 만들기 4 - 식당 목록 전달

파라미터

파라미터 전달을 위해서 Args 클래스를 추가하였습니다. Select, Result, Setting 클래스는 Args 클래스를 상속받도록 합니다.

# events/args.py

from conf.const import Const
import re


class Args:
    def __init__(self, args):
        self.args = args
        self.user_key = args.get(Const.ARG_USER_KEY)
        self.req_typ = args.get(Const.ARG_TYPE)
        content = args.get(Const.ARG_CONTENT)
        content = content.strip()
        self.content = re.sub('^#', '', content)

식당 목록 반환

Select 클래스에서 식당 목록을 보여줍니다.

  1. 사용자의 상태 정보 select_restaurant으로 변경합니다.

  2. 사용자의 그룹정보를 확인합니다.

    • 그룹정보가 없으면 그룹 선택 화면으로 이동합니다.
  3. 식당 목록을 확인합니다.

    • 등록된 식당이 없으면 시작 화면으로 이동합니다.
  4. 식당 목록을 배열로 생성합니다.

  5. 임의의 순서로 변경합니다.

  6. 정해진 수 만큼만 반환합니다.

# events/select

import operator
from random import shuffle

from firebase_admin import firestore

from conf.const import Const
from conf.firebaseInit import fs
from conf.util import Util
from events.args import Args


class Select(Args):
  def show_restaurant_list(self):
      # 상태 설정
      fs.collection(Const.COL_USER).document(self.user_key).update({
          Const.FIELD_STATE: Const.STATE_SELECT_RESTAURANT
      }, firestore.CreateIfMissingOption(True))

      # 그룹이 없으면 그룹 선택으로 보낸다.
      try:
          user = fs.collection(Const.COL_USER).document(self.user_key).get()
          user_group = user.get(Const.FIELD_GROUP)
      except:
          print("NotFound user")
          return self.show_group_list()

      try:
          # 해당 그룹의 식당목록을 가져온다.
          restaurant_list = []

          group = fs.collection(Const.COL_GROUP).document(user_group).get()
          restaurants = group.get(Const.FIELD_RESTAURANT)
          for key, val in restaurants.items():
              restaurant_list.append(key)
      except:
          print('No RESTAURANTS')
          return Util.show_start_menu('등록된 식당이 없습니다')

      shuffle(restaurant_list)

      if len(restaurant_list) > Const.SHOW_COUNT:
          restaurant_list = restaurant_list[:Const.SHOW_COUNT]

      restaurant_list.append(Const.BTN_GOTO_START)

      rst = {
          "message": {
              "text": '식당을 선택해 주세요'
          },
          "keyboard": {
              "type": "buttons",
              "buttons": restaurant_list
          }
      }

      return Util.send_response(rst)
fs.collection(Const.COL_USER).document(self.user_key).update({
    Const.FIELD_STATE: Const.STATE_SELECT_RESTAURANT
}, firestore.CreateIfMissingOption(True))

firestore는 컬렉션, 도큐먼트, 컬렉션, 도큐먼트, ... 로 구성되어 있습니다. 문서에 정보를 입력하는데, 기존의 정보가 있을 수도 있으므로 update를 사용하였습니다. 없는 경우 문서를 생성하기 위해 firestore.CreateIfMissingOption(True)를 추가하였습니다.

식당 목록

그룹 목록 화면

사용자의 상태를 그룹 선택으로 변경합니다. 그룹 목록을 가져와서 버튼 배열로 반환합니다.

# events/select

class Select(Args):
    # ...생략...
  
    def show_group_list(self):
        # 상태 설정
        fs.collection(Const.COL_USER).document(self.user_key).update({
            Const.FIELD_STATE: Const.STATE_SELECT_GROUP
        }, firestore.CreateIfMissingOption(True))

        # 그룹 목록 가져오기
        groups = fs.collection(Const.COL_GROUP).get()
        group_list = []
        for doc in groups:
            group_list.append(doc.id)

        group_list.append(Const.BTN_GOTO_START)

        rst = {
            "message": {
                "text": '그룹을 선택해 주세요'
            },
            "keyboard": {
                "type": "buttons",
                "buttons": group_list
            }
        }

        return Util.send_response(rst)

시작 화면

시작 화면 및 사용자의 입력과 상관이 없는 부분들을 처리하기 위해 Util 클래스를 생성하였습니다.

# conf/util.py

from datetime import datetime, timedelta
import re
import pytz
from flask import json, Response

from conf.const import Const


class Util:
    @classmethod
    def send_response(cls, rst):
        json_string = json.dumps(rst)
        response = Response(json_string, content_type="application/json; charset=utf-8")
        return response

    @classmethod
    def show_start_menu(cls, msg='원하는 메뉴를 선택해 주세요', img_src=None):
        if img_src:
            rst = {
                "message": {
                    "text": msg,
                    "photo": {
                        "url": img_src,
                        'width': 640,
                        "height": 480
                    }
                },
                "keyboard": {
                    "type": "buttons",
                    "buttons": Const.DEFAULT_KEYBOARD
                }
            }
        else:
            rst = {
                "message": {
                    "text": msg
                },
                "keyboard": {
                    "type": "buttons",
                    "buttons": Const.DEFAULT_KEYBOARD
                }
            }
        return Util.send_response(rst)

send_response 메소드를 통해서, object를 json으로 변경하여 반환합니다.

show_start_menu 메소드가 호출되면 시작화면으로 이동합니다.

댓글