요즘은 많은 공공기관에서 REST API를 제공하고 있다.

 

정식적으로 공공API를 사용하기 위해서는 활용신청 허가를 받아야한다.

 

https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15001106 

 

광주광역시 BIS 도착정보

광주광역시 BIS 도착정보에 대한 데이터를 제공하고 있습니다. 정류소 ID에 해당하는 정류소의 도착 정보 조회가 가능합니다.

www.data.go.kr

 

네이버로도 간편 회원가입을 할 수 있고, 휴대폰 인증을 거치면, 다음과 같이 간단히 신청을 할 수 있다.

 

참고 횟수는 데일리로 100회까지 지원이 되는 것 같다. 아직 정식으로 계속 필요한게 아니라서,

 

이정도로도 만족한다. (인증키가 공유되면 안되므로 가려놓음)

 

 

웹브라우저에서는 다음처럼 잘 불러와진다.

그리고 다음과 같이

import json
import requests
import pickle


def request_bus_info_from_api():
    service_key = 'TOP_SECRET'
    response = requests.get(f"http://api.gwangju.go.kr/json/arriveInfo?serviceKey={service_key}&BUSSTOP_ID=838")
    with open('temp_data.pickle', 'wb') as file:
        pickle.dump(response.content, file)


def load_bus_file():
    with open('temp_data.pickle', 'rb') as file:
        b_bus_stop_data = pickle.load(file)

    s_bus_stop_data = b_bus_stop_data.decode('utf-8')
    bus_stop_data = json.loads(s_bus_stop_data)
    return bus_stop_data


def get_bus_remain_info():
    bus_data = load_bus_file()
    result_list = list()
    for a_bus in bus_data['BUSSTOP_LIST']:
        result_list.append(str(a_bus['SHORT_LINE_NAME']))
        result_list.append(str(a_bus['REMAIN_STOP']))
        result_list.append(str(a_bus['REMAIN_MIN']))
    return result_list

버스 정보를 불러와서 피클로 저장해놓는 함수를 만들고,

import datetime
import sys

import PyQt5
import bus_info
from scratch_for_test import *


class MyBusInfoWindow(PyQt5.QtWidgets.QWidget, bus_info.Ui_MainWidget):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.refresh_count = 0
        self.init_pixmaps()
        self.init_labels_setting()
        self.init_timer()
        self.init_btn_mapping()
        self.label_status.hide()

    def init_btn_mapping(self):
        self.btn_refresh.clicked.connect(lambda state: self._clicked_refresh_btn())

    def init_pixmaps(self):
        self.green_good = PyQt5.QtGui.QPixmap('src/green_bus_good-removebg.png')
        self.green_doubt = PyQt5.QtGui.QPixmap('src/green_bus_doubt-removebg.png')
        self.green_worry = PyQt5.QtGui.QPixmap('src/green_bus_worry-removebg.png')
        self.yellow_good = PyQt5.QtGui.QPixmap('src/yellow_bus_good-removebg.png')
        self.yellow_doubt = PyQt5.QtGui.QPixmap('src/yellow_bus_doubt-removebg.png')
        self.yellow_worry = PyQt5.QtGui.QPixmap('src/yellow_bus_worry-removebg.png')

    def init_timer(self):
        self.inner_timer = PyQt5.QtCore.QTimer()
        self.inner_timer.setInterval(1000)  # 1초
        self.label_now_time.setText(self._get_now_time())
        self.inner_timer.timeout.connect(lambda: self.label_now_time.setText(self._get_now_time()))
        self.inner_timer.start()

        self.bus_refresh_timer = PyQt5.QtCore.QTimer()
        self.bus_refresh_timer.setInterval(1000 * 60)
        self._call_station_info()
        self.bus_refresh_timer.timeout.connect(lambda: self._call_station_info())
        self.bus_refresh_timer.timeout.connect(lambda: self.initialize_refresh_count())
        self.bus_refresh_timer.start()

    def _get_now_time(self):
        return datetime.datetime.now().strftime("%H:%M:%S")

    def initialize_refresh_count(self):
        self.refresh_count = 0
        self.label_status.hide()

    def init_labels_setting(self):
        self.frame_1_labels = list()
        self.frame_2_labels = list()
        self.frame_3_labels = list()
        self.frame_4_labels = list()
        self.frame_1_labels.append(self.frame_1_title)
        self.frame_1_labels.append(self.frame_1_time_left)
        self.frame_1_labels.append(self.frame_1_time_arrival)
        self.frame_1_labels.append(self.frame_1_time_left_title)
        self.frame_1_labels.append(self.frame_1_time_arrival_title)

        self.frame_2_labels.append(self.frame_2_title)
        self.frame_2_labels.append(self.frame_2_time_left)
        self.frame_2_labels.append(self.frame_2_time_arrival)
        self.frame_2_labels.append(self.frame_2_time_left_title)
        self.frame_2_labels.append(self.frame_2_time_arrival_title)

        self.frame_3_labels.append(self.frame_3_title)
        self.frame_3_labels.append(self.frame_3_time_left)
        self.frame_3_labels.append(self.frame_3_time_arrival)
        self.frame_3_labels.append(self.frame_3_time_left_title)
        self.frame_3_labels.append(self.frame_3_time_arrival_title)

        self.frame_4_labels.append(self.frame_4_title)
        self.frame_4_labels.append(self.frame_4_time_left)
        self.frame_4_labels.append(self.frame_4_time_arrival)
        self.frame_4_labels.append(self.frame_4_time_left_title)
        self.frame_4_labels.append(self.frame_4_time_arrival_title)

    def _call_station_info(self):
        request_bus_info_from_api()
        self.refresh_count += 1
        bus_info_list = get_bus_remain_info()
        for i in range(1, 5):
            for label in getattr(self, f'frame_{i}_labels'):
                label: PyQt5.QtWidgets.QLabel
                label.setText('')
        showing_size, temp = divmod(len(bus_info_list), 3)

        for i in range(1, showing_size + 1):
            temp_list = getattr(self, f'frame_{i}_labels')
            temp_list[0].setText(bus_info_list[(i - 1) * 3])
            temp_list[1].setText(bus_info_list[(i - 1) * 3 + 1] + ' 정거장')
            temp_list[2].setText(bus_info_list[(i - 1) * 3 + 2] + ' 분')
            temp_list[3].setText('남은 정류소')
            temp_list[4].setText('남은 도착시간')

        self._update_pixmap()

    def _clicked_refresh_btn(self):
        if self.refresh_count > 1:
            self.label_status.show()
            return
        else:
            self._call_station_info()

    def _update_pixmap(self):
        self.is_yellow_1 = self._assert_is_yellow_bus(1)
        self.is_yellow_2 = self._assert_is_yellow_bus(2)
        self.is_yellow_3 = self._assert_is_yellow_bus(3)
        self.is_yellow_4 = self._assert_is_yellow_bus(4)

        for i in range(1, 5):
            if getattr(self, f"frame_{i}_labels")[0].text() != '':
                if getattr(self, f"is_yellow_{i}") is True:
                    remain_time = int(getattr(self, f"frame_{i}_labels")[2].text()[:2].rstrip())
                    if remain_time > 8:
                        getattr(self, f"frame_{i}_img").setPixmap(self.yellow_good)
                    elif remain_time > 4:
                        getattr(self, f"frame_{i}_img").setPixmap(self.yellow_worry)
                    else:
                        getattr(self, f"frame_{i}_img").setPixmap(self.yellow_doubt)
                else:
                    remain_time = int(getattr(self, f"frame_{i}_labels")[2].text()[:2].rstrip())
                    if remain_time > 8:
                        getattr(self, f"frame_{i}_img").setPixmap(self.green_good)
                    elif remain_time > 4:
                        getattr(self, f"frame_{i}_img").setPixmap(self.green_worry)
                    else:
                        getattr(self, f"frame_{i}_img").setPixmap(self.green_doubt)
            self._assert_is_blank_cell_and_clear(i)

    def _assert_is_yellow_bus(self, index):
        if '봉선' in getattr(self, f'frame_{index}_labels')[0].text():
            return True
        else:
            return False

    def _assert_is_blank_cell_and_clear(self, index):
        if getattr(self, f'frame_{index}_labels')[0].text() == '':
            getattr(self, f'frame_{index}_img').clear()


if __name__ == '__main__':
    app = PyQt5.QtWidgets.QApplication(sys.argv)
    myWindow = MyBusInfoWindow()
    myWindow.show()
    app.exec_()

Qt에 적용시켜주는 로직을 만들어주면?

 

이런식으로 파일이 만들어진다.

 

그리고 간단하게 exe로 실행시킬 수 있게, pyinstaller를 적용해주면,

 

 

매번 pycharm을 실행시킬 필요 없이, 바탕화면에서도 버스 정보를 간단하게 불러올 수 있게 된다.

 

레전드오브복이 프로젝트 전부터 조금씩 진행중이던 개인프로젝트 였는데, 연휴동안 큰 탈 없이 마무리되었다.

 

이제 버스도착정보를 미리 보고 떠날 수 있으니, 시간낭비가 줄어들 것 같다.

 

직접 만든 프로그램을 유용하게 써먹을 수 있게 되어 기분이 좋다.

 

감사합니다.

 

 

+ Recent posts