mdj1412 commited on
Commit
8d21d0b
1 Parent(s): b476907

중간 수정(미완성)

Browse files
app.py CHANGED
@@ -29,38 +29,12 @@ demo_dic = get_list()
29
  ##### Home #####
30
  @app.route('/')
31
  def home_page():
32
- example_embed = 'This website analyzes stock market news and provides answers to questions related to news articles.'
33
- return render_template('index.html', embed=example_embed)# html을 불러올 때,
34
 
35
 
36
 
37
  ##### Data fetch #####
38
- @app.route('/submit', methods=['GET', 'POST'])
39
- def submit():
40
- input_text = request.args.get('input_text')
41
- return jsonify(result={"output":"My output is a summary of: "+input_text})
42
-
43
-
44
-
45
-
46
- @app.route('/model', methods=['GET', 'POST'])
47
- def model():
48
- print("\t\t Start model !!!")
49
-
50
- # Javascript 에서 받은 메시지
51
- text_input = request.args.get('text_input')
52
-
53
- print(f"Fetch from Javascript /inference, text_input : {text_input}")
54
-
55
- # modules/reference.py 에서 모델 적용
56
- output = Tk_instruct(text_input)
57
-
58
- text_output = {"text_output": output}
59
- print(f"Fetch from Javascript /inference, text_output : {text_output}")
60
- return jsonify(result=text_output)
61
-
62
-
63
-
64
 
65
  # Show Ticker's Table
66
  @app.route('/stocks', methods=['GET', 'POST'])
@@ -72,10 +46,6 @@ def stocks():
72
 
73
 
74
 
75
-
76
-
77
-
78
-
79
  ################################################################################################
80
 
81
 
@@ -86,12 +56,12 @@ ticker_dic = dict.fromkeys(demo_dic.ticker, []) # ticker1: [{날짜1: [제목1,
86
 
87
  dir = './news'
88
  if not os.path.exists(dir):
89
- raise NotImplementedError("Not exists News Data")# 오류 강제 발생
90
 
91
  # News Data List 가져오기
92
  for key in os.listdir(dir):
93
  if key not in ticker_dic.keys():
94
- raise NotImplementedError("Not exists Ticker")# 오류 강제 발생
95
 
96
  dir2 = os.path.join(dir, key)
97
  ticker_dic[key] = dict.fromkeys(os.listdir(dir2), []) # 날짜1: [제목1, 제목2, ...]
@@ -107,17 +77,6 @@ for key in os.listdir(dir):
107
  ticker_dic[key].pop(date)
108
 
109
 
110
- # from IPython import embed; embed()
111
-
112
-
113
-
114
- # Show Ticker's Title
115
- @app.route('/<ticker>', methods=['GET', 'POST'])
116
- def ticker(ticker):
117
- example_embed = "%s Chart" % (ticker)
118
-
119
- return render_template('chart.html', embed=example_embed)
120
-
121
 
122
  # Show Ticker's Data
123
  @app.route('/chart', methods=['GET', 'POST'])
@@ -133,32 +92,28 @@ def chart():
133
  # 날짜 형식 바꾸기
134
  chart_data.index = [k.strftime("%Y-%m-%d") for k in chart_data.index]
135
 
136
- result = chart_data.to_dict()
137
- return jsonify(result=result)
138
-
139
 
140
- @app.route('/news', methods=['GET', 'POST'])
141
- def news():
142
- print("Start /news ")
143
 
144
- # Javascript 에서 받은 메시지
145
- ticker = request.args.get('ticker')
146
 
147
  news_dir = os.path.join('./news', ticker)
148
 
149
  # 해당 Ticker의 날짜별 뉴스 제목을 가져온다.
150
- result = {}
151
  for key in os.listdir(news_dir):
152
  title_list = os.listdir(os.path.join(news_dir, key))
153
  if len(title_list) != 0:
154
- result[key] = os.listdir(os.path.join(news_dir, key))
155
 
156
  # 최근 뉴스부터 보이게 (정렬)
157
- sorted_result = {}
158
- for key, value in sorted(result.items(), reverse=True):
159
- sorted_result[key] = value
 
 
 
160
 
161
- return jsonify(result=sorted_result)
162
 
163
 
164
 
@@ -218,8 +173,10 @@ def ticker_title():
218
  example_embed3 = "Title: %s" % (title)
219
  example_embed4 = url
220
 
221
-
222
- return render_template('news_analysis.html', embed1=example_embed1, embed2=example_embed2, embed3=example_embed3, embed4=example_embed4)
 
 
223
 
224
 
225
 
 
29
  ##### Home #####
30
  @app.route('/')
31
  def home_page():
32
+ website_description_box = 'This website analyzes stock market news and provides answers to questions related to news articles.'
33
+ return render_template('index.html', embed=website_description_box)# html을 불러올 때,
34
 
35
 
36
 
37
  ##### Data fetch #####
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  # Show Ticker's Table
40
  @app.route('/stocks', methods=['GET', 'POST'])
 
46
 
47
 
48
 
 
 
 
 
49
  ################################################################################################
50
 
51
 
 
56
 
57
  dir = './news'
58
  if not os.path.exists(dir):
59
+ raise NotImplementedError("Not exists News Data") # 오류 강제 발생
60
 
61
  # News Data List 가져오기
62
  for key in os.listdir(dir):
63
  if key not in ticker_dic.keys():
64
+ raise NotImplementedError("Not exists Ticker") # 오류 강제 발생
65
 
66
  dir2 = os.path.join(dir, key)
67
  ticker_dic[key] = dict.fromkeys(os.listdir(dir2), []) # 날짜1: [제목1, 제목2, ...]
 
77
  ticker_dic[key].pop(date)
78
 
79
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  # Show Ticker's Data
82
  @app.route('/chart', methods=['GET', 'POST'])
 
92
  # 날짜 형식 바꾸기
93
  chart_data.index = [k.strftime("%Y-%m-%d") for k in chart_data.index]
94
 
95
+ chart_data = chart_data.to_dict()
 
 
96
 
 
 
 
97
 
98
+ ################
 
99
 
100
  news_dir = os.path.join('./news', ticker)
101
 
102
  # 해당 Ticker의 날짜별 뉴스 제목을 가져온다.
103
+ article_news_dict = {}
104
  for key in os.listdir(news_dir):
105
  title_list = os.listdir(os.path.join(news_dir, key))
106
  if len(title_list) != 0:
107
+ article_news_dict[key] = os.listdir(os.path.join(news_dir, key))
108
 
109
  # 최근 뉴스부터 보이게 (정렬)
110
+ news_articles = {}
111
+ for key, value in sorted(article_news_dict.items(), reverse=True):
112
+ news_articles[key] = value
113
+
114
+
115
+ return jsonify(chart_data=chart_data, news_articles=news_articles)
116
 
 
117
 
118
 
119
 
 
173
  example_embed3 = "Title: %s" % (title)
174
  example_embed4 = url
175
 
176
+ return '''
177
+ newsInit(example_embed1, example_embed2, example_embed3, example_embed4)
178
+ '''
179
+ # return render_template('news.html', embed1=example_embed1, embed2=example_embed2, embed3=example_embed3, embed4=example_embed4)
180
 
181
 
182
 
static/css/news.css CHANGED
@@ -112,13 +112,22 @@
112
 
113
  /* id : "#" */
114
  #model {
 
 
 
 
 
 
 
 
 
115
  text-align: center;
116
  }
117
 
118
  /* id : "#" */
119
  #text-input {
120
  width: calc(100% / 2); /* 속성의 요소 너비 */
121
- height: 78px;
122
  word-break: break-all;
123
  }
124
 
 
112
 
113
  /* id : "#" */
114
  #model {
115
+ /*
116
+ [ text-align 태그 ]
117
+ 텍스트의 정렬 방향을 설정
118
+
119
+ left: 왼쪽 정렬
120
+ right: 오른쪽 정렬
121
+ center: 중앙 정렬
122
+ justify: 양쪽 정렬 (자동 줄바꿈시 오른쪽 경계선 부분 정리)
123
+ */
124
  text-align: center;
125
  }
126
 
127
  /* id : "#" */
128
  #text-input {
129
  width: calc(100% / 2); /* 속성의 요소 너비 */
130
+ height: 78px; /* 속성의 요소의 높이를 지정 */
131
  word-break: break-all;
132
  }
133
 
static/js/cal.js ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * 달력 렌더링 할 때 필요한 정보 목록
3
+
4
+ 현재 월 (초기값 : 현재 시간)
5
+ 금월 마지막일 날짜와 요일
6
+ 전월 마지막일 날짜와 요일
7
+ */
8
+ function calendarInit() {
9
+
10
+ // 날짜 정보 가져오기
11
+ var date = new Date(); // 현재 날짜(로컬 기준) 가져오기
12
+ var utc = date.getTime() + (date.getTimezoneOffset() * 60 * 1000); // utc 표준시 도출
13
+ var kstGap = 9 * 60 * 60 * 100; // 한국 kst 기준시간 더하기
14
+ var today = new Date(utc + kstGap); // 한국 시간으로 date 객체 만들기(오늘)
15
+
16
+ console.log("Today : ", today)
17
+
18
+ // 달력에서 표기하는 날짜 객체
19
+ var thisMonth = new Date(today.getFullYear(), today.getMonth(), today.getDate());
20
+
21
+ var currentYear = thisMonth.getFullYear(); // 달력에서 표기하는 연
22
+ var currentMonth = thisMonth.getMonth(); // 달력에서 표기하는 월
23
+ var currentDate = thisMonth.getDate(); // 달력에서 표기하는 일
24
+
25
+ // kst 기준 현재시간
26
+ console.log("thisMonth");
27
+ console.log(currentYear);
28
+ console.log(currentMonth); // monthIndex
29
+ console.log(currentDate);
30
+ console.log(thisMonth);
31
+
32
+ // 캘린더 랜더링
33
+ renderCalender(thisMonth);
34
+
35
+
36
+ ////////////////////////////////////////////////////////////////
37
+
38
+ function renderCalender(thisMonth, help=0) {
39
+
40
+ // 랜더링을 위한 데이터 정리
41
+ currentYear = thisMonth.getFullYear();
42
+ currentMonth = thisMonth = thisMonth.getMonth();
43
+ if (help != 1) {
44
+ // currentDate = thisMonth.getDate(); // 1 - 31 : 1 - 31
45
+ currentDate = new Date(today.getFullYear(), today.getMonth(), today.getDate()).getDate();
46
+ }
47
+
48
+ // 이전 달의 마지막날 날짜와 요일 구하기
49
+ var startDay = new Date(currentYear, currentMonth, 0);
50
+ var prevDate = startDay.getDate(); // 1 - 31 : 1 - 31
51
+ var prevDay = startDay.getDay(); // Sunday - Saturday : 0 - 6
52
+
53
+ // 이번 달의 마지막날 날짜와 요일 구하기
54
+ var endDay = new Date(currentYear, currentMonth + 1 , 0);
55
+ var nextDate = endDay.getDate(); // 1 - 31 : 1 - 31
56
+ var nextDay = endDay.getDay(); // Sunday - Saturday : 0 - 6
57
+
58
+ // console.log(prevDate, prevDay, nextDate, nextDay, currentMonth);
59
+
60
+ // 현재 월 표기
61
+ $('.year-month').text(currentYear + '.' + (currentMonth + 1));
62
+
63
+ // 랜더링 html 요소 생성
64
+ calendar = document.querySelector('.dates')
65
+ calendar.innerHTML = '';
66
+
67
+ // 지난달
68
+ for (var i = prevDate - prevDay + 1; i <= prevDate; i++) {
69
+ calendar.innerHTML = calendar.innerHTML + '<div class="day prev disable">' + i + '</div>'
70
+ }
71
+
72
+ // 이번달
73
+ for (var i = 1; i <= nextDate; i++) {
74
+ calendar.innerHTML = calendar.innerHTML + '<div class="day current">' + i + '</div>'
75
+ }
76
+
77
+ // 다음달
78
+ for (var i = 1; i <= (7 - nextDay == 7 ? 0 : 7 - nextDay); i++) {
79
+ calendar.innerHTML = calendar.innerHTML + '<div class="day next disable">' + i + '</div>'
80
+ }
81
+
82
+ // 오늘 날짜 표기
83
+ if (today.getMonth() == currentMonth) {
84
+ todayDate = today.getDate();
85
+ var currentMonthDate = document.querySelectorAll('.dates .current'); // 중간 띄어쓰기 주의
86
+ // var currentMonthDate = document.querySelectorAll('div.day.current'); // 같은 의미
87
+
88
+ // console.log(currentMonthDate)
89
+ currentMonthDate[todayDate-1].classList.add('today');
90
+ }
91
+
92
+ // 이전달로 이동
93
+ $('.go-prev').on('click', function() {
94
+ if (help == 0) {
95
+ thisMonth = new Date(currentYear, currentMonth - 1, 1);
96
+ renderCalender(thisMonth, 1);
97
+ }
98
+ else {
99
+ renderCalender(thisMonth, 1);
100
+ }
101
+ })
102
+
103
+ // 다음달로 이동
104
+ $('.go-next').on('click', function() {
105
+ if (help == 0) {
106
+ thisMonth = new Date(currentYear, currentMonth + 1, 1);
107
+ renderCalender(thisMonth, 1);
108
+ }
109
+ else {
110
+ renderCalender(thisMonth, 1);
111
+ }
112
+ })
113
+ }
114
+ }
static/js/chartIndex.js CHANGED
@@ -7,15 +7,6 @@ $(function() {
7
 
8
 
9
 
10
-
11
- function handleReturn(output) {
12
- return output;
13
- }
14
-
15
-
16
-
17
-
18
-
19
  function chartInit() {
20
  // Ticker 이름 가져오기
21
  // 해당 class의 text 가져오기
@@ -26,7 +17,7 @@ function chartInit() {
26
 
27
 
28
  // Javascript -> Flask (Python) -> Javascript
29
- chart_data = sendAjax_async("/chart", {"ticker": ticker}, "json", handleReturn);
30
  console.log(chart_data);
31
  console.log(Object.keys(chart_data.Close));
32
 
@@ -44,8 +35,6 @@ function chartInit() {
44
  console.log("data : ", data);
45
 
46
 
47
-
48
-
49
 
50
 
51
  // Javascript chart.js candlestick
@@ -90,7 +79,7 @@ function chartInit() {
90
 
91
 
92
  // Javascript -> Flask (Python) -> Javascript
93
- news = sendAjax_async(url="/news", data={"ticker": ticker}, dataType="json", handle=handleReturn);
94
 
95
  news_table = document.querySelector('.table .news-table');
96
  // console.log(news_table.innerHTML);
@@ -177,70 +166,4 @@ function chartInit() {
177
 
178
  news_table.innerHTML = news_table.innerHTML + html;
179
  });
180
- }
181
-
182
-
183
-
184
-
185
-
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
- /**
198
- *
199
- * @param {string} url from javascript to flask(python) with route
200
- * @param {dictionary} data from javascript to flask(python) with data
201
- * @param {function} handle 큰 의미 없음
202
- */
203
- function sendAjax(url, data, handle) {
204
- /*
205
- jQuery.getJSON(url, [, data], [, success])
206
-
207
- Load JSON-encoded data from the server using a GET HTTP request.
208
- */
209
-
210
- $.getJSON(url, data,
211
- function(response) {
212
- handle(response.result);
213
- });
214
- }
215
-
216
-
217
- /**
218
- *
219
- * @param {string} url from javascript to flask(python) with route
220
- * @param {dictionary} data from javascript to flask(python) with data
221
- * @param {string} dataType The type of data that you're expecting back from the server. (ex. "json")
222
- * @param {function} handle 큰 의미 없음
223
- * @returns from flask(python) to javascript with data
224
- */
225
- function sendAjax_async(url, data, dataType, handle) {
226
- /*
227
- jQuery.ajax(url, [, settings])
228
-
229
- jQuery.getJSON => Asynchronous (비동기식)
230
-
231
- Synchronous => 동기식 : 코드 순서대로 진행
232
- */
233
-
234
- var search_var;
235
- console.log("Internal : sendAjax async");
236
-
237
- $.ajax(url=url, settings={data: data, dataType: dataType, async: false,
238
- success: function(response) {
239
- console.log("Success : ", typeof response);
240
- search_var = handle(response.result); // handle, 큰 의미 없음
241
- }
242
- });
243
-
244
- return search_var
245
- }
246
-
 
7
 
8
 
9
 
 
 
 
 
 
 
 
 
 
10
  function chartInit() {
11
  // Ticker 이름 가져오기
12
  // 해당 class의 text 가져오기
 
17
 
18
 
19
  // Javascript -> Flask (Python) -> Javascript
20
+ chart_data = sendAjax_sync("/chart", {"ticker": ticker}, "json", handle_one_return);
21
  console.log(chart_data);
22
  console.log(Object.keys(chart_data.Close));
23
 
 
35
  console.log("data : ", data);
36
 
37
 
 
 
38
 
39
 
40
  // Javascript chart.js candlestick
 
79
 
80
 
81
  // Javascript -> Flask (Python) -> Javascript
82
+ news = sendAjax_sync(url="/news", data={"ticker": ticker}, dataType="json", handle=handle_one_return);
83
 
84
  news_table = document.querySelector('.table .news-table');
85
  // console.log(news_table.innerHTML);
 
166
 
167
  news_table.innerHTML = news_table.innerHTML + html;
168
  });
169
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
static/js/index.js CHANGED
@@ -13,7 +13,6 @@
13
 
14
 
15
 
16
-
17
  /*
18
  ".ready()"는 DOM(Document Object Model)이 완전히 불러와지면 실행되는 Event 이다.
19
 
@@ -28,34 +27,61 @@
28
  ( 근데 여기서는 실행 문제 잘됨 )
29
  */
30
 
 
 
 
 
 
31
  // $(document).ready(function() { });
32
  $(function() {
33
- console.log("Start debug !!");
 
 
 
 
34
 
35
- stocksInit();
36
- // calendarInit();
 
 
 
 
 
 
37
  });
38
 
39
 
40
 
41
 
42
 
43
- function handleReturn(output) {
44
- return output;
45
- }
46
 
47
 
48
 
49
- function stocksInit() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  // Javascript -> Flask (Python) -> Javascript
51
- output = sendAjax_async("/stocks", {}, "json", handleReturn);
52
 
53
- console.log("stocksInit() Output : ", output);
54
- console.log(typeof output);
55
 
56
  // Ticker 길이 확인해보기
57
  var object_length = Object.keys(output.ticker).length;
58
- console.log(object_length);
59
 
60
 
61
  // 랜더링 HTML 요소 생성
@@ -76,10 +102,10 @@ function stocksInit() {
76
  stocks.innerHTML = stocks.innerHTML + '<div class="stock industry">' + output.industry[i] + '</div>';
77
 
78
  // Add ticker's chart link
79
- link = String('"/'.concat(output.ticker[i], '"'));
80
  stock = document.querySelectorAll('.stock.ticker')[i];
81
  stock.innerHTML = '';
82
- stock.innerHTML = stock.innerHTML + '<a href='.concat(link, '>') + output.ticker[i] + '</a>';
83
  }
84
  }
85
 
@@ -88,172 +114,362 @@ function stocksInit() {
88
 
89
 
90
 
91
- /**
92
- * 달력 렌더링 할 때 필요한 정보 목록
93
 
94
- 현재 월 (초기값 : 현재 시간)
95
- 금월 마지막일 날짜와 요일
96
- 전월 마지막일 날짜와 요일
 
 
 
 
 
 
 
97
  */
98
- function calendarInit() {
 
 
 
 
99
 
100
- // 날짜 정보 가져오기
101
- var date = new Date(); // 현재 날짜(로컬 기준) 가져오기
102
- var utc = date.getTime() + (date.getTimezoneOffset() * 60 * 1000); // utc 표준시 도출
103
- var kstGap = 9 * 60 * 60 * 100; // 한국 kst 기준시간 더하기
104
- var today = new Date(utc + kstGap); // 한국 시간으로 date 객체 만들기(오늘)
105
 
106
- console.log("Today : ", today)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
- // 달력에서 표기하는 날짜 객체
109
- var thisMonth = new Date(today.getFullYear(), today.getMonth(), today.getDate());
110
 
111
- var currentYear = thisMonth.getFullYear(); // 달력에서 표기하는 연
112
- var currentMonth = thisMonth.getMonth(); // 달력에서 표기하는 월
113
- var currentDate = thisMonth.getDate(); // 달력에서 표기하는 일
114
 
115
- // kst 기준 현재시간
116
- console.log("thisMonth");
117
- console.log(currentYear);
118
- console.log(currentMonth); // monthIndex
119
- console.log(currentDate);
120
- console.log(thisMonth);
121
 
122
- // 캘린더 랜더���
123
- renderCalender(thisMonth);
 
 
 
 
 
 
 
 
 
124
 
125
 
126
- ////////////////////////////////////////////////////////////////
127
 
128
- function renderCalender(thisMonth, help=0) {
129
 
130
- // 랜더링을 위한 데이터 정리
131
- currentYear = thisMonth.getFullYear();
132
- currentMonth = thisMonth = thisMonth.getMonth();
133
- if (help != 1) {
134
- // currentDate = thisMonth.getDate(); // 1 - 31 : 1 - 31
135
- currentDate = new Date(today.getFullYear(), today.getMonth(), today.getDate()).getDate();
136
- }
137
 
138
- // 이전 달의 마지막날 날짜와 요일 구하기
139
- var startDay = new Date(currentYear, currentMonth, 0);
140
- var prevDate = startDay.getDate(); // 1 - 31 : 1 - 31
141
- var prevDay = startDay.getDay(); // Sunday - Saturday : 0 - 6
142
 
143
- // 이번 달의 마지막날 날짜와 요일 구하기
144
- var endDay = new Date(currentYear, currentMonth + 1 , 0);
145
- var nextDate = endDay.getDate(); // 1 - 31 : 1 - 31
146
- var nextDay = endDay.getDay(); // Sunday - Saturday : 0 - 6
147
 
148
- // console.log(prevDate, prevDay, nextDate, nextDay, currentMonth);
 
 
 
149
 
150
- // 현재 월 표기
151
- $('.year-month').text(currentYear + '.' + (currentMonth + 1));
152
 
153
- // 랜더링 html 요소 생성
154
- calendar = document.querySelector('.dates')
155
- calendar.innerHTML = '';
156
 
157
- // 지난달
158
- for (var i = prevDate - prevDay + 1; i <= prevDate; i++) {
159
- calendar.innerHTML = calendar.innerHTML + '<div class="day prev disable">' + i + '</div>'
160
- }
161
 
162
- // 이번달
163
- for (var i = 1; i <= nextDate; i++) {
164
- calendar.innerHTML = calendar.innerHTML + '<div class="day current">' + i + '</div>'
165
- }
166
 
167
- // 다음달
168
- for (var i = 1; i <= (7 - nextDay == 7 ? 0 : 7 - nextDay); i++) {
169
- calendar.innerHTML = calendar.innerHTML + '<div class="day next disable">' + i + '</div>'
170
- }
171
 
172
- // 오늘 날짜 표기
173
- if (today.getMonth() == currentMonth) {
174
- todayDate = today.getDate();
175
- var currentMonthDate = document.querySelectorAll('.dates .current'); // 중간 띄어쓰기 주의
176
- // var currentMonthDate = document.querySelectorAll('div.day.current'); // 같은 의미
177
 
178
- // console.log(currentMonthDate)
179
- currentMonthDate[todayDate-1].classList.add('today');
180
- }
 
181
 
182
- // 이전달로 이동
183
- $('.go-prev').on('click', function() {
184
- if (help == 0) {
185
- thisMonth = new Date(currentYear, currentMonth - 1, 1);
186
- renderCalender(thisMonth, 1);
187
- }
188
- else {
189
- renderCalender(thisMonth, 1);
190
- }
191
- })
192
 
193
- // 다음달로 이동
194
- $('.go-next').on('click', function() {
195
- if (help == 0) {
196
- thisMonth = new Date(currentYear, currentMonth + 1, 1);
197
- renderCalender(thisMonth, 1);
198
- }
199
- else {
200
- renderCalender(thisMonth, 1);
201
- }
202
- })
203
- }
204
- }
205
 
 
 
206
 
207
 
 
 
 
208
 
209
 
210
 
211
- /**
212
- *
213
- * @param {string} url from javascript to flask(python) with route
214
- * @param {dictionary} data from javascript to flask(python) with data
215
- * @param {function} handle 큰 의미 없음
216
- */
217
- function sendAjax(url, data, handle) {
218
- /*
219
- jQuery.getJSON(url, [, data], [, success])
220
 
221
- Load JSON-encoded data from the server using a GET HTTP request.
 
 
 
 
222
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
- $.getJSON(url, data,
225
- function(response) {
226
- handle(response.result);
227
- });
228
  }
229
 
230
 
 
 
 
 
 
 
 
231
  /**
232
  *
233
- * @param {string} url from javascript to flask(python) with route
234
- * @param {dictionary} data from javascript to flask(python) with data
235
- * @param {string} dataType The type of data that you're expecting back from the server. (ex. "json")
236
- * @param {function} handle 큰 의미 없음
237
- * @returns from flask(python) to javascript with data
 
 
 
 
238
  */
239
- function sendAjax_async(url, data, dataType, handle) {
240
- /*
241
- jQuery.ajax(url, [, settings])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
- jQuery.getJSON => Asynchronous (비동기식)
244
-
245
- Synchronous => 동기식 : 코드 순서대로 진행
246
- */
247
 
248
- var search_var;
249
- console.log("Internal : sendAjax async");
 
 
250
 
251
- $.ajax(url=url, settings={data: data, dataType: dataType, async: false,
252
- success: function(response) {
253
- console.log("Success : ", typeof response);
254
- search_var = handle(response.result); // handle, 큰 의미 없음
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  }
256
  });
257
-
258
- return search_var
259
  }
 
 
13
 
14
 
15
 
 
16
  /*
17
  ".ready()"는 DOM(Document Object Model)이 완전히 불러와지면 실행되는 Event 이다.
18
 
 
27
  ( 근데 여기서는 실행 문제 잘됨 )
28
  */
29
 
30
+
31
+
32
+
33
+
34
+
35
  // $(document).ready(function() { });
36
  $(function() {
37
+ var nasdaq_table_container_element = document.getElementById("nasdaq-table-container");
38
+ var chart_container_element = document.getElementById("chart-container");
39
+ var news_container_element = document.getElementById("news-container");
40
+ console.log(nasdaq_table_container_element, chart_container_element, news_container_element);
41
+
42
 
43
+ // nasdaq_table_container_element.style.display = "block";
44
+ // chart_container_element.style.display = "none";
45
+ // news_container_element.style.display = "none";
46
+ // $("#news-container").hide();
47
+ // $("#news-container").show();
48
+
49
+
50
+ nasdaq_table_init();
51
  });
52
 
53
 
54
 
55
 
56
 
 
 
 
57
 
58
 
59
 
60
+
61
+
62
+
63
+
64
+
65
+ /**
66
+ *
67
+ *
68
+ *
69
+ *
70
+ */
71
+ function nasdaq_table_init() {
72
+ // HTML 수정
73
+ $("#chart-container").hide();
74
+ $("#news-container").hide();
75
+
76
  // Javascript -> Flask (Python) -> Javascript
77
+ output = sendAjax_sync("/stocks", {}, "json", handle_one_return);
78
 
79
+ // console.log("stocksInit() Output : ", output);
80
+ // console.log(typeof output);
81
 
82
  // Ticker 길이 확인해보기
83
  var object_length = Object.keys(output.ticker).length;
84
+ // console.log(object_length);
85
 
86
 
87
  // 랜더링 HTML 요소 생성
 
102
  stocks.innerHTML = stocks.innerHTML + '<div class="stock industry">' + output.industry[i] + '</div>';
103
 
104
  // Add ticker's chart link
105
+ execution_function = String('"javascript:chartInit(\''.concat(output.ticker[i], '\');"'));
106
  stock = document.querySelectorAll('.stock.ticker')[i];
107
  stock.innerHTML = '';
108
+ stock.innerHTML = stock.innerHTML + '<a href='.concat(execution_function, '>') + output.ticker[i] + '</a>';
109
  }
110
  }
111
 
 
114
 
115
 
116
 
 
 
117
 
118
+
119
+ /**
120
+ *
121
+ *
122
+ *
123
+ *
124
+ *
125
+ *
126
+ *
127
+ *
128
  */
129
+ function chartInit(ticker) {
130
+ // HTML 수정
131
+ $("#nasdaq-table-container").hide();
132
+ $("#chart-container").show();
133
+ $("#news-container").hide();
134
 
135
+ // ticker 이름 설정 (부제목 설정)
136
+ $('#chart-container .goticker .tickerName').text(ticker.concat(' Chart'));
 
 
 
137
 
138
+ // Javascript -> Flask (Python) -> Javascript
139
+ let [chart_data, news_articles] = sendAjax_sync_about_chartData_and_newsArticles("/chart", {"ticker": ticker}, "json", handle_two_return);
140
+ // console.log(chart_data, news_articles);
141
+ // console.log(chart_data);
142
+ // console.log(Object.keys(chart_data.Close));
143
+
144
+
145
+ // x축과 data 설정
146
+ // data: [{'x': date, 'o': open, 'h': high, 'l': low, 'c': close}, { }, { }, ... ]
147
+ data = [];
148
+ key_list = Object.keys(chart_data.Close);
149
+ for (var i=key_list.length-15; i<key_list.length; i++) {
150
+ key = key_list[i];
151
+ const [year, month, day] = key.split("-");
152
+ const x = new Date(parseInt(year), parseInt(month), parseInt(day), 9, 0, 0, 0).getTime();
153
+ data.push({'x': x, 'o': chart_data.Open[key].toFixed(2), 'h': chart_data.High[key].toFixed(2), 'l': chart_data.Low[key].toFixed(2), 'c': chart_data.Close[key].toFixed(2)})
154
+ }
155
+ // console.log("data : ", data);
156
 
 
 
157
 
 
 
 
158
 
 
 
 
 
 
 
159
 
160
+ // Javascript chart.js candlestick
161
+ let mychart = document.getElementById('myChart');
162
+ new Chart(mychart, {
163
+ type: 'candlestick',
164
+ data: {
165
+ datasets: [{
166
+ label: 'CHRT - '.concat(ticker),
167
+ data: data
168
+ }]
169
+ }
170
+ });
171
 
172
 
 
173
 
 
174
 
 
 
 
 
 
 
 
175
 
176
+ //////////////////////////////////////////////////////////////////
 
 
 
177
 
178
+ // Javascript를 이용해 HTML에 동적으로 태그 추가
 
 
 
179
 
180
+ // a 태그 onclick 적용
181
+ execution_function = String('javascript:chartInit(\''.concat(ticker, '\');'));
182
+ const goTicker = document.querySelector('.goticker');
183
+ goTicker.setAttribute('href', execution_function);
184
 
185
+ //////////////////////////////////////////////////////////////////
 
186
 
 
 
 
187
 
 
 
 
 
188
 
 
 
 
 
189
 
 
 
 
 
190
 
191
+ //////////////////////////////////////////////////////////////////
 
 
 
 
192
 
193
+ // table title 표시
194
+ // 해당 class의 text 집어넣기
195
+ const table_title = document.querySelector('.table-title');
196
+ $('.table .table-title').text(ticker.concat(' News'));
197
 
 
 
 
 
 
 
 
 
 
 
198
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
200
+ news_table = document.querySelector('.table .news-table');
201
+ // console.log(news_table.innerHTML);
202
 
203
 
204
+ // console.log(news);
205
+ // console.log(Object.keys(news)); // key 배열 만들기
206
+ // console.log(typeof Object.keys(news));
207
 
208
 
209
 
 
 
 
 
 
 
 
 
 
210
 
211
+ /*
212
+ [ 날짜 정렬 ]
213
+ "news"에서 index에 대해서 정렬을 하고 reduce() 함수를 적용.
214
+
215
+ reduce() : 배열의 각 요소에 대해 주어진 reducer 함수를 실행하고, 하나의 결과값을 반환
216
  */
217
+ sorted_news = {}
218
+ sorted_news = Object.keys(news_articles).sort(function (a, b) {
219
+ if (a < b) { return 1; }
220
+ else if (a > b) { return -1; }
221
+ else { return 0; }
222
+ }).reduce((sorted_news, key) => {
223
+ sorted_news[key] = news_articles[key];
224
+ return sorted_news;
225
+ }, {});
226
+ // console.log(sorted_news);
227
+
228
+ var key_list = Object.keys(chart_data.Open);
229
+ var open_list = Object.values(chart_data.Open);
230
+ var close_list = Object.values(chart_data.Close);
231
+
232
+ for (var i=0; i<key_list.length; i++) {
233
+ const [year, month, day] = key_list[i].split("-");
234
+ key_list[i] = year + '.' + month + '.' + day;
235
+ }
236
+ // console.log(key_list);
237
+
238
+ // List 안의 value를 뽑을 때, (Python) => for item in list:
239
+ Object.keys(sorted_news).forEach(key => {
240
+ var idx = key_list.indexOf(String(key));
241
+
242
+ if (idx != -1) { var diff = ((open_list[idx]-close_list[idx-1])/(open_list[idx]) * 100.0).toFixed(2); }
243
+ else { var diff = '.'; }
244
+
245
+ if (diff == '.') {
246
+ var diff_html = '<th class="news diff">' + diff + '</th>';
247
+ }
248
+ else if (diff > 0) {
249
+ var diff_html = '<th class="news diff up">+' + diff + ' %</th>';
250
+ }
251
+ else {
252
+ var diff_html = '<th class="news diff down">' + diff + ' %</th>';
253
+ }
254
+ var html = '<tr align="center" bgcolor="white"><th>+</th><th>' + key + '</th>' + diff_html + '<td style="text-align: left;">';
255
+
256
+ for (var i = 0; i < sorted_news[key].length; i++) {
257
+ var title = sorted_news[key][i].substring(0, sorted_news[key][i].length-4);
258
+ var sendTitle = title; // Javascript -> Python 보내기 위한 title
259
+ console.log("title : ", title);
260
+
261
+
262
+ // title에서 & 표시가 있을 수 있음.
263
+ // Title 에서 '&'로 표시되어 있는데 따로 구별해야 된다.
264
+ // andSymbolInTitle 에서 가져온 '&' 위치 index를 title과 합쳐준다.
265
+ andSymbolInTitle = [];
266
+ let idx = 0;
267
+ // title = "asdf&asdf&AS&DF&&";
268
+ // sendTitle = title;
269
+
270
+ while (true) {
271
+ idx = sendTitle.indexOf('&', idx);
272
+ if (idx == -1) { break; }
273
+ sendTitle = sendTitle.substring(0, idx) + sendTitle.substring(idx+1, sendTitle.length);
274
+ // console.log(sendTitle);
275
+ andSymbolInTitle.push(idx + andSymbolInTitle.length);
276
+ }
277
+ // console.log("title : ", title);
278
+ // console.log("sendTitle : ", sendTitle);
279
+ // console.log("andSymbolInTitle : ", andSymbolInTitle);
280
+
281
+ var link = String('"/info?ticker='.concat(ticker, '&date=', key, '&title=', sendTitle, '&andSymbolInTitle=', andSymbolInTitle, '"'));
282
+ // console.log(link);
283
+
284
+ var execution_function = String(`javascript:newsInit(\'${ticker}\',\'${key}\',\'${sendTitle}\',\'${andSymbolInTitle}\');`);
285
+ // console.log("execution_function : ", execution_function);
286
+ html = html + '<a href=' + link + '>' + title + '</a><br>';
287
+ }
288
+ html = html + '</td>';
289
 
290
+ news_table.innerHTML = news_table.innerHTML + html;
291
+ });
 
 
292
  }
293
 
294
 
295
+
296
+
297
+
298
+
299
+
300
+
301
+
302
  /**
303
  *
304
+ *
305
+ *
306
+ *
307
+ *
308
+ *
309
+ *
310
+ *
311
+ *
312
+ *
313
  */
314
+ function newsInit(ticker1, date1, title1, andSymbolInTitle1) {
315
+ console.log("newsInit start");
316
+ // HTML 수정
317
+ $("#nasdaq-table-container").hide();
318
+ $("#chart-container").hide();
319
+ $("#news-container").show();
320
+
321
+ spaceIndex_inTitle = andSymbolInTitle1.split(',');
322
+ var list_length = spaceIndex_inTitle.length;
323
+ for (var i=0; i<list_length; i++) {
324
+ title1 = title1.substring(0, i) + ' ' + title1.substring(i, title1.length);
325
+ }
326
+
327
+ console.log(ticker1);
328
+ console.log(date1);
329
+ console.log(title1);
330
+ console.log(andSymbolInTitle1);
331
+
332
+
333
+
334
+ //////////////////////////////////////////////////////////////////////
335
+
336
+ // Javascript를 이용해 HTML에 동적으로 태그 추가
337
+
338
 
 
 
 
 
339
 
340
+ // a 태그 onclick 적용
341
+ execution_function = String('javascript:chartInit(\''.concat(ticker, '\');'));
342
+ const goTicker = document.querySelector('.goticker');
343
+ goTicker.setAttribute('href', execution_function);
344
 
345
+
346
+ // a 태그에 URL 적용
347
+ const addURL = document.querySelector('.NewsURL .input-News-URL');
348
+ addURL.setAttribute('href', url);
349
+
350
+
351
+ // 모델에서 질문 예시 Ticker에 알맞게 작성하기
352
+ const example_value = document.querySelector('#model .text-form #text-input');
353
+ example = "Why did " + ticker + "'s stock go down?";
354
+ example_value.setAttribute('value', example);
355
+
356
+
357
+ //////////////////////////////////////////////////////////////////////
358
+ // NER 관련
359
+
360
+ ents = sendAjax_sync('/ner', {'ticker': ticker, 'date': date, 'title': title}, dataType="json", handle=handle_one_return);
361
+ // ents = {'text': [], 'start_char': [], 'end_char': [], 'label_': [], 'news': []}
362
+ console.log(ents);
363
+
364
+ let news = ents['news'];
365
+ let numOfNER = ents['text'].length;
366
+
367
+
368
+ // 랜더링 html 요소 생성
369
+ news_ner = document.querySelector('.entities');
370
+ news_ner.innerHTML = '';
371
+
372
+ for (i=0; i<numOfNER-1; i++) {
373
+ start_idx = (i == 0) ? 0 : ents['end_char'][i-1];
374
+ end_idx = ents['start_char'][i];
375
+ last_idx = ents['end_char'][i];
376
+
377
+ label = ents['label_'][i];
378
+ if (label == 'ORG') { class_name = "entity_org"; }
379
+ else if (label == 'PERSON') { class_name = "entity_person"; }
380
+ else if (label == 'FAC') { class_name = "entity_fac"; }
381
+ else if (label == 'GPE') { class_name = "entity_gpe"; }
382
+ else if (label == 'PRODUCT') { class_name = "entity_product"; }
383
+ else { console.log("[ Error !!! - New NER label_ ] : ", ents['label_'][i], ents['text'][i]); class_name = "none"; }
384
+
385
+ news_ner.innerHTML = news_ner.innerHTML + news.substring(start_idx, end_idx);
386
+ news_ner.innerHTML = news_ner.innerHTML + '<mark class=' + class_name
387
+ + ' style="line-height: 1;">'
388
+ + news.substring(end_idx, last_idx)
389
+ + '<span class="show-label" style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">'
390
+ + label + '</span></mark>';
391
+ }
392
+ news_ner.innerHTML = news_ner.innerHTML + news.substring(ents['end_char'][numOfNER-1]);
393
+
394
+
395
+
396
+
397
+ //////////////////////////////////////////////////////////////////////
398
+ // 모델 적용 내용 ( Submit )
399
+
400
+ var sendTitle = title; // Javascript -> Python 보내기 위한 title
401
+
402
+
403
+ // title에서 & 표시가 있을 수 있음.
404
+ // Title 에서 '&'로 표시되어 있는데 따로 구별해야 된다.
405
+ // andSymbolInTitle 에서 가져온 '&' 위치 index를 title과 합쳐준다.
406
+ andSymbolInTitle = [];
407
+ let idx = 0;
408
+ // title = "asdf&asdf&AS&DF&&";
409
+ // sendTitle = title;
410
+
411
+ while (true) {
412
+ idx = sendTitle.indexOf('&', idx);
413
+ if (idx == -1) { break; }
414
+ sendTitle = sendTitle.substring(0, idx) + sendTitle.substring(idx+1, sendTitle.length);
415
+ console.log(sendTitle);
416
+ andSymbolInTitle.push(idx + andSymbolInTitle.length);
417
+ }
418
+
419
+ console.log(andSymbolInTitle);
420
+ console.log("Last String", sendTitle);
421
+
422
+
423
+
424
+ // function 앞에 "async"를 붙이면 해당 함수는 항상 프라미스를 반환한다.
425
+ const translateText = async (text) => {
426
+ // 목적 : Flask에 input을 보내주고 output을 받아오는 과정
427
+ console.log("Start translateText async");
428
+
429
+ // "await"는 "async" 함수 안에서만 동작한다.
430
+ // "await" 키워드를 만나면 Promise가 처리될 때까지 기다린다.
431
+ // Promise가 처리되길 기다리는 동안엔 엔진이 다른일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않는다.
432
+ const inferResponse = await fetch(`newsQuestions?ticker=${ticker}&date=${date}&title=${sendTitle}&andSymbolInTitle=${andSymbolInTitle}&questions=${text}`); // Javascript -> Flask(python)
433
+
434
+ // console.log("inferResponse : ", inferResponse);
435
+
436
+ const inferJson = await inferResponse.json(); // Flask(python) -> Javascript
437
+
438
+ // console.log(inferJson);
439
+ return inferJson.result['answer'];
440
+ };
441
+
442
+
443
+ /* 모델 Submit button 관련 내용 */
444
+ // form 태그의 class 이름
445
+ const textForm = document.querySelector('.text-form');
446
+
447
+
448
+ // addEventListener(type, listener)
449
+ // addEventListener(type, listener, options)
450
+ // addEventListener(type, listener, useCapture)
451
+ textForm.addEventListener('submit', async (event) => {
452
+ event.preventDefault();
453
+ // console.log(event);
454
+
455
+ // html -> javascript : input 받아와서 output 보내기
456
+ const textInput = document.getElementById('text-input');
457
+ const textParagraph = document.querySelector('.text-output');
458
+
459
+ console.log("textInput : ", textInput, textInput.value);
460
+ try {
461
+ // sendAjax("/inference", {"input_text" : textInput.value}, handleOutput);
462
+
463
+ // "await"는 "async" 함수 안에서만 동작한다.
464
+ // "await" 키워드를 만나면 Promise가 처리될 때까지 기다린다.
465
+ // Promise가 처리되길 기다리는 동안엔 엔진이 다른일(다른 스크립트를 실행, 이벤트 처리 등)을 할 수 있기 때문에, CPU 리소스가 낭비되지 않는다.
466
+ const answer = await translateText(textInput.value); // Flask에 input을 보내주고 output을 받아오는 과정
467
+
468
+ console.log("Answer : ", answer);
469
+ textParagraph.textContent = answer;
470
+ } catch (err) {
471
+ console.error(err);
472
  }
473
  });
 
 
474
  }
475
+
static/js/news.js CHANGED
@@ -54,7 +54,7 @@ function newsInit() {
54
  //////////////////////////////////////////////////////////////////////
55
  // NER 관련
56
 
57
- ents = sendAjax_async('/ner', {'ticker': ticker, 'date': date, 'title': title}, dataType="json", handle=handleReturn);
58
  // ents = {'text': [], 'start_char': [], 'end_char': [], 'label_': [], 'news': []}
59
  console.log(ents);
60
 
@@ -81,7 +81,7 @@ function newsInit() {
81
 
82
  news_ner.innerHTML = news_ner.innerHTML + news.substring(start_idx, end_idx);
83
  news_ner.innerHTML = news_ner.innerHTML + '<mark class=' + class_name
84
- + ' style="margin: 0 0.25em; line-height: 1;">'
85
  + news.substring(end_idx, last_idx)
86
  + '<span class="show-label" style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">'
87
  + label + '</span></mark>';
@@ -159,6 +159,7 @@ function newsInit() {
159
 
160
  // html -> javascript : input 받아와서 output 보내기
161
  const textInput = document.getElementById('text-input');
 
162
  const textParagraph = document.querySelector('.text-output');
163
 
164
  console.log("textInput : ", textInput, textInput.value);
@@ -176,79 +177,6 @@ function newsInit() {
176
  console.error(err);
177
  }
178
  });
179
-
180
-
181
-
182
-
183
-
184
-
185
- }
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
- /**
201
- *
202
- * @param {string} url from javascript to flask(python) with route
203
- * @param {dictionary} data from javascript to flask(python) with data
204
- * @param {function} handle 큰 의미 없음
205
- */
206
- function sendAjax(url, data, handle) {
207
- /*
208
- jQuery.getJSON(url, [, data], [, success])
209
-
210
- Load JSON-encoded data from the server using a GET HTTP request.
211
- */
212
-
213
- $.getJSON(url, data,
214
- function(response) {
215
- handle(response.result);
216
- });
217
  }
218
 
219
 
220
- /**
221
- *
222
- * @param {string} url from javascript to flask(python) with route
223
- * @param {dictionary} data from javascript to flask(python) with data
224
- * @param {string} dataType The type of data that you're expecting back from the server. (ex. "json")
225
- * @param {function} handle 큰 의미 없음
226
- * @returns from flask(python) to javascript with data
227
- */
228
- function sendAjax_async(url, data, dataType, handle) {
229
- /*
230
- jQuery.ajax(url, [, settings])
231
-
232
- jQuery.getJSON => Asynchronous (비동기식)
233
-
234
- Synchronous => 동기식 : 코드 순서대로 진행
235
- */
236
-
237
- var search_var;
238
- console.log("Internal : sendAjax async");
239
-
240
- $.ajax(url=url, settings={data: data, dataType: dataType, async: false,
241
- success: function(response) {
242
- console.log("Success : ", typeof response);
243
- search_var = handle(response.result); // handle, 큰 의미 없음
244
- }
245
- });
246
-
247
- return search_var
248
- }
249
-
250
-
251
-
252
- function handleReturn(output) {
253
- return output;
254
- }
 
54
  //////////////////////////////////////////////////////////////////////
55
  // NER 관련
56
 
57
+ ents = sendAjax_sync('/ner', {'ticker': ticker, 'date': date, 'title': title}, dataType="json", handle=handle_one_return);
58
  // ents = {'text': [], 'start_char': [], 'end_char': [], 'label_': [], 'news': []}
59
  console.log(ents);
60
 
 
81
 
82
  news_ner.innerHTML = news_ner.innerHTML + news.substring(start_idx, end_idx);
83
  news_ner.innerHTML = news_ner.innerHTML + '<mark class=' + class_name
84
+ + ' style="line-height: 1;">'
85
  + news.substring(end_idx, last_idx)
86
  + '<span class="show-label" style="font-size: 0.8em; font-weight: bold; line-height: 1; border-radius: 0.35em; vertical-align: middle; margin-left: 0.5rem">'
87
  + label + '</span></mark>';
 
159
 
160
  // html -> javascript : input 받아와서 output 보내기
161
  const textInput = document.getElementById('text-input');
162
+ console.log("element : ", textInput);
163
  const textParagraph = document.querySelector('.text-output');
164
 
165
  console.log("textInput : ", textInput, textInput.value);
 
177
  console.error(err);
178
  }
179
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  }
181
 
182
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
static/js/utils.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * helper functions defined
3
+ */
4
+
5
+ function handle_one_return(output) {
6
+ return output;
7
+ }
8
+ function handle_two_return(output1, output2) {
9
+ return [output1, output2];
10
+ }
11
+
12
+
13
+
14
+ /**
15
+ *
16
+ * @param {string} url from javascript to flask(python) with route
17
+ * @param {dictionary} data from javascript to flask(python) with data
18
+ * @param {function} handle 큰 의미 없음
19
+ */
20
+ function sendAjax(url, data, handle) {
21
+ /*
22
+ jQuery.getJSON(url, [, data], [, success])
23
+
24
+ Load JSON-encoded data from the server using a GET HTTP request.
25
+ */
26
+
27
+ $.getJSON(url, data,
28
+ function(response) {
29
+ handle(response.result);
30
+ }
31
+ );
32
+ }
33
+
34
+
35
+ /**
36
+ *
37
+ * @param {string} url from javascript to flask(python) with route
38
+ * @param {dictionary} data from javascript to flask(python) with data
39
+ * @param {string} dataType The type of data that you're expecting back from the server. (ex. "json")
40
+ * @param {function} handle 큰 의미 없음
41
+ * @returns from flask(python) to javascript with data
42
+ */
43
+ function sendAjax_sync(url, data, dataType, handle) {
44
+ /*
45
+ jQuery.ajax(url, [, settings])
46
+
47
+ jQuery.getJSON => Asynchronous (비동기식)
48
+
49
+ Synchronous => 동기식 : 코드 순서대로 진행
50
+ */
51
+ var search_var;
52
+ $.ajax(url=url, settings={data: data, dataType: dataType, async: false,
53
+ success: function(response) {
54
+ search_var = handle(response.result); // handle, 큰 의미 없음
55
+ }
56
+ });
57
+
58
+ return search_var
59
+ }
60
+
61
+
62
+
63
+ /**
64
+ *
65
+ * @param {string} url from javascript to flask(python) with route
66
+ * @param {dictionary} data from javascript to flask(python) with data
67
+ * @param {string} dataType The type of data that you're expecting back from the server. (ex. "json")
68
+ * @param {function} handle 큰 의미 없음
69
+ * @returns from flask(python) to javascript with data
70
+ */
71
+ function sendAjax_sync_about_chartData_and_newsArticles(url, data, dataType, handle) {
72
+ /*
73
+ jQuery.ajax(url, [, settings])
74
+
75
+ jQuery.getJSON => Asynchronous (비동기식)
76
+
77
+ Synchronous => 동기식 : 코드 순서대로 진행
78
+ */
79
+ var chart_data;
80
+ var news_articles;
81
+ $.ajax(url=url, settings={data: data, dataType: dataType, async: false,
82
+ success: function(response) {
83
+ [chart_data, news_articles] = handle(response.chart_data, response.news_articles); // handle, 큰 의미 없음
84
+ }
85
+ });
86
+
87
+ return [chart_data, news_articles];
88
+ }
89
+
templates/chart.html CHANGED
@@ -13,66 +13,18 @@
13
  <!-- jQuery -->
14
  <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
15
  <!-- script 태그 : 외부 js 파일을 연결하거나 javascript 코드를 입력할 때 사용 -->
 
16
  <script type="text/javascript" src="static/js/chartIndex.js"></script>
17
 
18
 
19
 
20
 
21
 
22
-
23
-
24
- <!-- Recharts -->
25
- <!-- <script src="https://unpkg.com/react/umd/react.production.min.js"></script>
26
- <script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
27
-
28
- <script src="https://unpkg.com/prop-types/prop-types.min.js"></script>
29
- <script src="https://unpkg.com/recharts/umd/Recharts.js"></script> -->
30
-
31
- <!-- <script src="https://unpkg.com/recharts/umd/Recharts.min.js"></script> -->
32
-
33
-
34
-
35
-
36
-
37
-
38
  <script src="https://cdn.jsdelivr.net/npm/luxon@1.26.0"></script>
39
  <script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.1/dist/chart.js"></script>
40
  <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.0.0"></script>
41
  <script src="static/js/chartjs-chart-financial.js" type="text/javascript"></script>
42
 
43
-
44
-
45
-
46
- <!-- 보류 모르겠음 ... -->
47
-
48
- <!-- ========================================================================================= -->
49
-
50
-
51
- <!-- Include Chart.js from a CDN -->
52
-
53
- <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.1/chart.min.js"></script> -->
54
- <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.2.1/chart.js"></script> -->
55
- <!-- <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> -->
56
-
57
-
58
- <!-- <script src="https://cdn.jsdelivr.net/npm/luxon@1.26.0"></script>
59
- <script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.1/dist/chart.js"></script>
60
- <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.0.0"></script>
61
-
62
-
63
- <script src="https://cdn.jsdelivr.net/npm/luxon@1.26.0"></script>
64
- <script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.1/dist/chart.js"></script>
65
- <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.0.0"></script>
66
-
67
- <script src="https://www.chartjs.org/chartjs-chart-financial/chartjs-chart-financial.js"></script> -->
68
-
69
-
70
-
71
- <!--
72
- CDN : Content Delivery Network
73
- 지리적 제약 없이 전 세계 사용자에게 빠르고 안전하게 콘텐츠를 전송할 수 있는 '콘텐츠 전송 기술을 의미'
74
- 서버와 사용자 사이의 물리적인 거리를 줄여 콘텐츠 로딩에 소요되는 시간을 최소화한다.
75
- -->
76
  </head>
77
 
78
 
 
13
  <!-- jQuery -->
14
  <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
15
  <!-- script 태그 : 외부 js 파일을 연결하거나 javascript 코드를 입력할 때 사용 -->
16
+ <script type="text/javascript" src="static/js/utils.js"></script>
17
  <script type="text/javascript" src="static/js/chartIndex.js"></script>
18
 
19
 
20
 
21
 
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  <script src="https://cdn.jsdelivr.net/npm/luxon@1.26.0"></script>
24
  <script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.1/dist/chart.js"></script>
25
  <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.0.0"></script>
26
  <script src="static/js/chartjs-chart-financial.js" type="text/javascript"></script>
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  </head>
29
 
30
 
templates/index.html CHANGED
@@ -12,43 +12,186 @@
12
  <link rel="stylesheet" href="static/css/style.css" />
13
 
14
  <!-- jQuery -->
15
- <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
16
  <!-- script 태그 : 외부 js 파일을 연결하거나 javascript 코드를 입력할 때 사용 -->
 
17
  <script type="text/javascript" src="static/js/index.js"></script>
18
 
 
 
 
 
 
 
 
19
  </head>
20
 
21
 
22
 
 
 
 
 
 
 
 
 
23
 
24
  <!-- body 태그 : 본문에 해당하는 부분, 실제 보여지는 화면에 해당 -->
25
  <body>
26
- <h1><a class="gohome" href="" onclick="sendAjax('/', undefined, undefined);"> Stock News NER & Analysis </a></h1>
27
- <p id='embed'>{{embed}}</p>
28
 
29
- <p id='mylog'/>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
 
32
- <!-- [ id class 차이 ] -->
33
- <!-- id : 문서에 하나의 요소에만 적용(중복X) -->
34
- <!-- id : 특정 요소에 이름을 붙이는데 사용 -->
35
- <!-- class : 동일한 값을 갖는 요소 많음 -->
36
- <!-- class : 스타일의 분류에 사용 -->
37
-
38
-
39
- <div class="stocks_wrap">
40
- <div class="stocks_columns">
41
- <div class="column ticker">Ticker</div>
42
- <div class="column name">Name</div>
43
- <div class="column dff">Diff</div>
44
- <div class="column open">Open</div>
45
- <div class="column close">Close</div>
46
- <div class="column sector">Sector</div>
47
- <div class="column industry">Industry</div>
48
  </div>
49
 
50
- <div class="stocks"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  </div>
52
 
 
 
 
53
  </body>
54
  </html>
 
12
  <link rel="stylesheet" href="static/css/style.css" />
13
 
14
  <!-- jQuery -->
15
+ <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.4/jquery.min.js'></script>
16
  <!-- script 태그 : 외부 js 파일을 연결하거나 javascript 코드를 입력할 때 사용 -->
17
+ <script type="text/javascript" src="static/js/utils.js"></script>
18
  <script type="text/javascript" src="static/js/index.js"></script>
19
 
20
+
21
+
22
+ <!-- Draw Chart Library -->
23
+ <script src="https://cdn.jsdelivr.net/npm/luxon@1.26.0"></script>
24
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@3.0.1/dist/chart.js"></script>
25
+ <script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.0.0"></script>
26
+ <script src="static/js/chartjs-chart-financial.js" type="text/javascript"></script>
27
  </head>
28
 
29
 
30
 
31
+ <!-- [ id class 차이 ] -->
32
+ <!-- id : 한 문서에 단 하나의 요소에만 적용(중복X) -->
33
+ <!-- id : 특정 요소에 이름을 붙이는데 사용 -->
34
+ <!-- class : 동일한 값을 갖는 요소 많음 -->
35
+ <!-- class : 스타일의 분류에 사용 -->
36
+
37
+
38
+
39
 
40
  <!-- body 태그 : 본문에 해당하는 부분, 실제 보여지는 화면에 해당 -->
41
  <body>
 
 
42
 
43
+ <!-- block = show, none = hide -->
44
+ <div id="nasdaq-table-container" style="display: block">
45
+ <h1><a class="gohome" style="text-decoration: none;" href="" onclick="sendAjax('/', undefined, undefined);"> Stock News NER & Analysis </a></h1>
46
+ <p id='embed'>{{embed}}</p>
47
+
48
+ <p id='mylog' />
49
+
50
+ <div class="stocks_wrap">
51
+ <div class="stocks_columns">
52
+ <div class="column ticker">Ticker</div>
53
+ <div class="column name">Name</div>
54
+ <div class="column dff">Diff</div>
55
+ <div class="column open">Open</div>
56
+ <div class="column close">Close</div>
57
+ <div class="column sector">Sector</div>
58
+ <div class="column industry">Industry</div>
59
+ </div>
60
+
61
+ <div class="stocks"></div>
62
+ </div>
63
+ </div>
64
 
65
 
66
+
67
+ <!-- block = show, none = hide -->
68
+ <div id="chart-container" style="display: block">
69
+ <h1><a class="gohome" style="text-decoration: none;" href="/">Stock News Summaries AI</a></h1>
70
+ <a class="goticker" style="text-decoration: none;"><h2 class="tickerName"></h2></a>
71
+
72
+ <div>
73
+ <div id="chart-container" width="974" height="486"></div>
74
+
75
+ <div class="myChart-container">
76
+ <canvas id="myChart"></canvas>
77
+ </div>
78
+
 
 
 
79
  </div>
80
 
81
+ <!--
82
+ [ 속성 ]
83
+
84
+ align : 정렬을 지정한다. (left, center, right)
85
+ border : 테두리 선의 두께를 지정한다.
86
+ bgcolor : 배경색을 지정한다. (색은 "red", "black" 처럼 기존의 정의되어있는 색을 사용할 수도 있으며
87
+ rgb형식의 #000000 으로도 색을 지정할 수 있다.)
88
+ bordercolor : 테두리 선의 색을 지정한다. 색을 지정하는 방법은 bgcolor와 동일하다.
89
+ cellspacing : 셀간의 간격을 지정한다.
90
+ width : 가로 길이를 지정한다. (상수 값을 입력할 수도, % 단위로 입력할 수 있다.
91
+ %를 사용할 때는 웹브라우저 크기에 대한 % 이다.)
92
+ height : 세로 길이를 지정한다.
93
+ rawspan : 지정한 값만큼 행을 병합한다. (위아래로)
94
+ colspan : 지정한 값만큼 열을 병합한다. (좌우로)
95
+ -->
96
+
97
+
98
+ <!-- table 태그 : 테이블을 만든다. -->
99
+ <table class="table"
100
+
101
+ text-align="center"
102
+ align-items="center"
103
+ justify-content="center"
104
+
105
+ border="1"
106
+ width="90%"
107
+ height="200"
108
+ cellspacing="5">
109
+
110
+
111
+ <!-- caption 태그 : 테이블 이름 표시 -->
112
+ <caption class="table-title"></caption>
113
+
114
+ <!-- 테이블의 헤더 영역 지정 -->
115
+ <thread>
116
+ <!-- tr 태그 : 테이블읠 행(가로 한줄)을 만든다. -->
117
+ <tr align="center" bgcolor="white">
118
+ <!-- td 태그 : 테이블의 열을 만든다. -->
119
+ <td width="5%"></td>
120
+
121
+ <!-- th 태그 : 테이블(표)의 헤드 부분(자동으로 가운데 정렬, 굵게 적용) -->
122
+ <th width="10%">Date</th>
123
+ <th width="10%">Diff</th>
124
+ <th class="title-width">Articles</th>
125
+ </tr>
126
+ </thread>
127
+
128
+ <!-- tbody 태그 : -->
129
+ <tbody class="news-table">
130
+ <!-- News: Date, Diff, Title 추가 -->
131
+ </tbody>
132
+
133
+ </table>
134
+ </div>
135
+
136
+
137
+
138
+ <!-- block = show, none = hide -->
139
+ <div id="news-container" style="display: block">
140
+ <h1><a class="gohome" style="text-decoration: none;" href="/">Stock News Summaries AI</a></h1>
141
+ <a class="goticker" style="text-decoration: none;"><h2 class="tickerName">{{embed1}}</h2></a>
142
+ <h3 class="titleDate">{{embed2}}</h2>
143
+ <h3 class="titleName">{{embed3}}</h2>
144
+ <h3 class="NewsURL">URL: <a class="input-News-URL" target=”_blank”>{{embed4}}</a></h2>
145
+
146
+ <!-- named entity recognition (NER) -->
147
+ <figure style="margin-bottom: 6rem">
148
+ <div class="entities" style="line-height: 2.5; direction: ltr">
149
+
150
+ </div>
151
+ </figure>
152
+
153
+
154
+ <!-- section 태그 : HTML 문서에 포함된 독립적인 섹션을 정의할 때 사용 -->
155
+ <section id="model">
156
+ <h2>Questions about Stock's News</h2>
157
+
158
+ <!-- p 태그 : paragraph, 즉 문단의 약자로, 하나의 문단을 만들 때 사용 -->
159
+ <p>
160
+ Model :
161
+
162
+ <!-- target="_blank" : 기본속성 중 하나로 클릭시 계속해서 새로운 창이 열리게 된다. -->
163
+ <a
164
+ href="https://huggingface.co/allenai/tk-instruct-base-def-pos"
165
+ rel="noeferrer"
166
+ target="_blank">Tk-instruct Model</a
167
+ >
168
+ </p>
169
+
170
+
171
+ <!-- form 태그 : 데이터를 전송하기 위한 태그 -->
172
+ <!-- form 태그 : 데이터를 전송할 url (action 속성) -->
173
+ <!-- form 태그 : 데이터 전달 방식이 get인지 post인지 결정 (method 속성) -->
174
+ <form class="text-form">
175
+
176
+ <!-- label 태그는 for 속성을 사용해서 input 태그의 id 속성에 연계해서 사용 -->
177
+ <label for="text-input">[ Questions ]</label> <br>
178
+ <input
179
+ id="text-input"
180
+ type="text"
181
+ placeholder="Input Questions"
182
+ value="Why did Alphabet's stock go down?"
183
+ />
184
+
185
+ <button id="text-submit">Submit</button>
186
+ <p> [ Answer ] </p>
187
+ <p class="text-output"></p>
188
+ </form>
189
+
190
+ </section>
191
  </div>
192
 
193
+
194
+
195
+
196
  </body>
197
  </html>
templates/news_analysis.html DELETED
@@ -1,88 +0,0 @@
1
- <!-- html 태그 : HTML로 작성되어 있다는 것을 알려줌 -->
2
- <!-- html 태그 : html 파일 전체를 감싸는 태그 -->
3
- <html>
4
- <!-- head 태그 : 머리말에 해당 -->
5
- <!-- head 태그 : css나 javascript를 연결해줌 -->
6
- <!-- head 태그 : 파비콘이나 문자열 인코딩과 같은 문서의 다양한 정보를 제공 -->
7
- <head>
8
-
9
- <!-- link 태그 : 주로 외부 css 파일을 연결할 때 사용 -->
10
- <link rel="stylesheet" href="static/css/news.css" />
11
-
12
- <!-- jQuery -->
13
- <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>
14
- <!-- script 태그 : 외부 js 파일을 연결하거나 javascript 코드를 입력할 때 사용 -->
15
- <script type="text/javascript" src="static/js/news.js"></script>
16
-
17
-
18
- </head>
19
-
20
-
21
-
22
- <!-- body 태그 : 본문에 해당하는 부분, 실제 보여지는 화면에 해당 -->
23
- <body>
24
- <h1><a class="gohome" href="/">Stock News Summaries AI</a></h1>
25
- <a class="goticker"><h2 class="tickerName">{{embed1}}</h2></a>
26
- <h3 class="titleDate">{{embed2}}</h2>
27
- <h3 class="titleName">{{embed3}}</h2>
28
- <h3 class="NewsURL">URL: <a class="input-News-URL" target=”_blank”>{{embed4}}</a></h2>
29
-
30
-
31
-
32
- <!-- named entity recognition (NER) -->
33
- <figure style="margin-bottom: 6rem">
34
- <div class="entities" style="line-height: 2.5; direction: ltr">
35
-
36
- </div>
37
- </figure>
38
-
39
-
40
-
41
-
42
- <!-- section 태그 : HTML 문서에 포함된 독립적인 섹션을 정의할 때 사용 -->
43
- <section id="model">
44
- <h2>Questions about Stock's News</h2>
45
-
46
- <!-- p 태그 : paragraph, 즉 문단의 약자로, 하나의 문단을 만들 때 사용 -->
47
- <p>
48
- Model :
49
-
50
- <!-- target="_blank" : 기본속성 중 하나로 클릭시 계속해서 새로운 창이 열리게 된다. -->
51
- <a
52
- href="https://huggingface.co/allenai/tk-instruct-base-def-pos"
53
- rel="noeferrer"
54
- target="_blank">Tk-instruct Model</a
55
- >
56
- </p>
57
-
58
-
59
- <!-- form 태그 : 데이터를 전송하기 위한 태그 -->
60
- <!-- form 태그 : 데이터를 전송할 url (action 속성) -->
61
- <!-- form 태그 : 데이터 전달 방식이 get인지 post인지 결정 (method 속성) -->
62
- <form class="text-form">
63
-
64
- <!-- label 태그는 for 속성을 사용해서 input 태그의 id 속성에 연계해서 사용 -->
65
- <label for="text-input">[ Questions ]</label> <br>
66
- <input
67
- id="text-input"
68
- type="text"
69
- placeholder="Input Questions"
70
- value="Why did Alphabet's stock go down?"
71
- />
72
-
73
- <button id="text-submit">Submit</button>
74
- <p> [ Answer ] </p>
75
- <p class="text-output"></p>
76
- </form>
77
-
78
- </section>
79
-
80
-
81
-
82
-
83
-
84
- </body>
85
-
86
-
87
-
88
- </html>