Showing
14 changed files
with
418 additions
and
279 deletions
.DS_Store
0 → 100644
No preview for this file type
1.png
0 → 100644

68.2 KB
1 | -## 트위터 내 계정 분석 사이트 | 1 | +### http://khuhub.khu.ac.kr/2018110654/term-project 의 프로젝트를 깃허브로 이동하였습니다. |
2 | + | ||
3 | +# 트위터 내 계정 분석 사이트 | ||
2 | <img src="images/main.png"> | 4 | <img src="images/main.png"> |
3 | 5 | ||
4 | -http://www.twitter-analyze.ml | 6 | + |
7 | +http://www.twitter-analyze.ml:3000/ | ||
5 | 서버가 켜져있다면 위의 url으로 접속할 수도 있습니다. | 8 | 서버가 켜져있다면 위의 url으로 접속할 수도 있습니다. |
9 | + | ||
6 | 10 | ||
7 | ## 프로젝트 소개 | 11 | ## 프로젝트 소개 |
8 | 검색한 트위터 계정의 **타임라인을 분석하는 사이트**입니다.</br> | 12 | 검색한 트위터 계정의 **타임라인을 분석하는 사이트**입니다.</br> |
... | @@ -25,14 +29,12 @@ http://www.twitter-analyze.ml | ... | @@ -25,14 +29,12 @@ http://www.twitter-analyze.ml |
25 | ## 빌드방법 | 29 | ## 빌드방법 |
26 | 30 | ||
27 | > <https://developer.twitter.com/en></br> | 31 | > <https://developer.twitter.com/en></br> |
28 | - | ||
29 | _위 링크에서 twiiter api key를 발급받고 코드에 발급받은 key를 삽입해주세요 | 32 | _위 링크에서 twiiter api key를 발급받고 코드에 발급받은 key를 삽입해주세요 |
30 | 33 | ||
31 | > npm install | 34 | > npm install |
32 | > npm install twitter | 35 | > npm install twitter |
33 | 36 | ||
34 | _terminal에서 위의 명령어를 작성해주세요_ | 37 | _terminal에서 위의 명령어를 작성해주세요_ |
35 | - | ||
36 | 38 | ||
37 | 39 | ||
38 | > npm install twitter | 40 | > npm install twitter |
... | @@ -43,7 +45,6 @@ _terminal에서 위의 명령어를 작성해주세요_ | ... | @@ -43,7 +45,6 @@ _terminal에서 위의 명령어를 작성해주세요_ |
43 | _위의 명령어가 작동하지 않는다면 이 명령어로 시도하세요_ | 45 | _위의 명령어가 작동하지 않는다면 이 명령어로 시도하세요_ |
44 | 46 | ||
45 | ## 사용방법 | 47 | ## 사용방법 |
46 | - | ||
47 | 1. 타임라인 검색 기능 | 48 | 1. 타임라인 검색 기능 |
48 | - 메인페이지에 있는 검색창에 보고싶은 계정의 아이디(ex)@twitterKorea)를 검색해 타임라인을 볼 수 있습니다. | 49 | - 메인페이지에 있는 검색창에 보고싶은 계정의 아이디(ex)@twitterKorea)를 검색해 타임라인을 볼 수 있습니다. |
49 | <img src="images/timeline.png"> | 50 | <img src="images/timeline.png"> |
... | @@ -53,7 +54,7 @@ _위의 명령어가 작동하지 않는다면 이 명령어로 시도하세요_ | ... | @@ -53,7 +54,7 @@ _위의 명령어가 작동하지 않는다면 이 명령어로 시도하세요_ |
53 | <img src="images/search.png"> | 54 | <img src="images/search.png"> |
54 | 55 | ||
55 | - 이 때 내가 리트윗한 게시물도 포함해 검색합니다 | 56 | - 이 때 내가 리트윗한 게시물도 포함해 검색합니다 |
56 | - <img src="images/retweet search.png"> | 57 | + <img src="images/retweet%20search.png"> |
57 | 58 | ||
58 | 3. 인기글 보여주기 기능 | 59 | 3. 인기글 보여주기 기능 |
59 | - 현재 해당계정에서 인기있는 글들을 모아 보여줍니다. | 60 | - 현재 해당계정에서 인기있는 글들을 모아 보여줍니다. | ... | ... |
package-lock.json
0 → 100644
This diff is collapsed. Click to expand it.
package.json
0 → 100644
1 | { | 1 | { |
2 | - "name": "express-tutorial", | ||
3 | - "version": "1.0.0", | ||
4 | - "dependencies": | ||
5 | - { | ||
6 | - "express": "~4.13.1", | ||
7 | - "ejs": "~2.4.1" | ||
8 | - } | ||
9 | - } | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
2 | + "name": "express-tutorial", | ||
3 | + "version": "1.0.0", | ||
4 | + "dependencies": { | ||
5 | + "express": "~4.13.1", | ||
6 | + "ejs": "~2.4.1", | ||
7 | + "twitter": "^1.7.1" | ||
8 | + } | ||
9 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
public/.DS_Store
0 → 100644
No preview for this file type
... | @@ -7,10 +7,10 @@ app.set('views', __dirname + '/views'); //서버가 읽을 수 있도록 HTML | ... | @@ -7,10 +7,10 @@ app.set('views', __dirname + '/views'); //서버가 읽을 수 있도록 HTML |
7 | app.set('view engine', 'ejs'); //서버가 HTML 렌더링을 할 때, EJS 엔진을 사용하도록 설정합니다. | 7 | app.set('view engine', 'ejs'); //서버가 HTML 렌더링을 할 때, EJS 엔진을 사용하도록 설정합니다. |
8 | app.engine('html', require('ejs').renderFile); | 8 | app.engine('html', require('ejs').renderFile); |
9 | 9 | ||
10 | -app.get('/timeline/:screen_name',tweetsController.getUserTweets); // '/timeline/:screen_name'형식의 url이 들어오면 뒤의 함수를 실행시킴 | 10 | +app.get('/timeline/:screen_name', tweetsController.getUserTweets); // '/timeline/:screen_name'형식의 url이 들어오면 뒤의 함수를 실행시킴 |
11 | -app.get('/timeline/:screen_name/:keyword',tweetsController.getUserTweetsForSearch); | 11 | +app.get('/timeline/:screen_name/:keyword', tweetsController.getUserTweetsForSearch); |
12 | -app.get('/popular/:screen_name',tweetsController.getUserRetweet);//'/hot/:screen_name'형식의 url이 들어오면 뒤의 함수를 실행시킴 | 12 | +app.get('/popular/:screen_name', tweetsController.getUserRetweet);//'/hot/:screen_name'형식의 url이 들어오면 뒤의 함수를 실행시킴 |
13 | -var server = app.listen(3000, function(){ //3000 포트 사용 | 13 | +var server = app.listen(3000, function () { //3000 포트 사용 |
14 | console.log("Express server has started on port 3000"); | 14 | console.log("Express server has started on port 3000"); |
15 | }) | 15 | }) |
16 | 16 | ... | ... |
1 | const Twitter = require('twitter'); | 1 | const Twitter = require('twitter'); |
2 | 2 | ||
3 | const client = new Twitter({ | 3 | const client = new Twitter({ |
4 | - consumer_key: 'key1', | 4 | + consumer_key: "consumer_key", |
5 | - consumer_secret: 'key2', | 5 | + consumer_secret: "consumer_secret", |
6 | - access_token_key: 'key3', | 6 | + access_token_key: "access_token_key", |
7 | - access_token_secret: 'key4' | 7 | + access_token_secret: "access_token_secret" |
8 | 8 | ||
9 | }); | 9 | }); |
10 | 10 | ||
11 | 11 | ||
12 | -exports.getUserTweets = async function(req, res){ //전체 타임라인 | 12 | +exports.getUserTweets = async function (req, res) { //전체 타임라인 |
13 | - try{ | 13 | + try { |
14 | - let data = client.get('statuses/user_timeline', req.params, function(error,tweets,response){ //트위터 api에서 유저의 타임라인을 가져옴 req.params에 유저 아이디가 들어있음 | 14 | + let data = client.get('statuses/user_timeline', req.params, function (error, tweets, response) { //트위터 api에서 유저의 타임라인을 가져옴 req.params에 유저 아이디가 들어있음 |
15 | - if(!error){ | 15 | + if (!error) { |
16 | - | 16 | + |
17 | console.log(tweets); //가져온 타임라인 내용 콘솔창에 출력 | 17 | console.log(tweets); //가져온 타임라인 내용 콘솔창에 출력 |
18 | - res.render('timeline.html',{ timeline: tweets}); //timeline.html 화면에 뿌려줌 그리고 tweets값을 저 페이지로 보냄 | 18 | + res.render('timeline.html', { timeline: tweets }); //timeline.html 화면에 뿌려줌 그리고 tweets값을 저 페이지로 보냄 |
19 | + } | ||
20 | + else { | ||
21 | + let msg = "" | ||
22 | + if (response.statusCode === 404) | ||
23 | + msg = "User not found." | ||
24 | + else { | ||
25 | + try { | ||
26 | + msg = error[0].message | ||
27 | + } | ||
28 | + catch { | ||
29 | + } | ||
30 | + } | ||
31 | + | ||
32 | + res.render('error.html', { statusCode: response.statusCode, msg: msg }); | ||
33 | + | ||
19 | } | 34 | } |
20 | }); //아이디를 토대로 타임라인 가져오기 | 35 | }); //아이디를 토대로 타임라인 가져오기 |
21 | - | ||
22 | 36 | ||
23 | - }catch(err){ //에러 발생하면 실행 | 37 | + |
38 | + } catch (err) { //에러 발생하면 실행 | ||
39 | + res.render('error.html', { statusCode: 500, msg: String(err) }); | ||
24 | console.log(err); | 40 | console.log(err); |
25 | res.sendStatus(500); | 41 | res.sendStatus(500); |
26 | } | 42 | } |
27 | } | 43 | } |
28 | 44 | ||
29 | -exports.getUserTweetsForSearch = async function(req, res){ //검색 | 45 | +exports.getUserTweetsForSearch = async function (req, res) { //검색 |
30 | - try{ | 46 | + try { |
31 | - let data = client.get('statuses/user_timeline', req.params, function(error,tweets,response){ //트위터 api에서 유저의 타임라인을 가져옴 req.params에 유저 아이디가 들어있음 | 47 | + let data = client.get('statuses/user_timeline', req.params, function (error, tweets, response) { //트위터 api에서 유저의 타임라인을 가져옴 req.params에 유저 아이디가 들어있음 |
32 | - if(!error){ | 48 | + if (!error) { |
33 | - res.render('search.html',{ timeline: tweets, keyword:req.params.keyword}); //timeline.html 화면에 뿌려줌 그리고 tweets값을 저 페이지로 보냄 | 49 | + res.render('search.html', { timeline: tweets, keyword: req.params.keyword }); //timeline.html 화면에 뿌려줌 그리고 tweets값을 저 페이지로 보냄 |
50 | + | ||
34 | console.log(req.params); | 51 | console.log(req.params); |
35 | } | 52 | } |
53 | + else { | ||
54 | + let msg = "" | ||
55 | + if (response.statusCode === 404) | ||
56 | + msg = "User not found." | ||
57 | + else { | ||
58 | + try { | ||
59 | + msg = error[0].message | ||
60 | + } | ||
61 | + catch { | ||
62 | + } | ||
63 | + } | ||
64 | + | ||
65 | + res.render('error.html', { statusCode: response.statusCode, msg: msg }); | ||
66 | + } | ||
36 | }); //아이디를 토대로 타임라인 가져오기 | 67 | }); //아이디를 토대로 타임라인 가져오기 |
37 | 68 | ||
38 | - }catch(err){ //에러 발생하면 실행 | 69 | + } catch (err) { //에러 발생하면 실행 |
39 | console.log(err); | 70 | console.log(err); |
71 | + res.render('error.html', { statusCode: 500, msg: String(err) }); | ||
72 | + | ||
40 | res.sendStatus(500); | 73 | res.sendStatus(500); |
41 | } | 74 | } |
42 | } | 75 | } |
43 | 76 | ||
44 | 77 | ||
45 | -exports.getUserRetweet = async function(req, res){ //인기있는 글 | 78 | +exports.getUserRetweet = async function (req, res) { //인기있는 글 |
46 | - try{ | 79 | + try { |
47 | - let retweetdata = client.get('statuses/user_timeline', req.params, function(error, tweets, response) {//리트윗 | 80 | + let retweetdata = client.get('statuses/user_timeline', req.params, function (error, tweets, response) {//리트윗 |
48 | - if(!error){ | 81 | + if (!error) { |
49 | - tweets.sort(function(a,b){ | 82 | + tweets.sort(function (a, b) { |
50 | - return b.retweet_count-a.retweet_count; | 83 | + return b.retweet_count - a.retweet_count; |
51 | - });//리트윗 data 내림차순로 정렬(?) | 84 | + });//리트윗 data 내림차순로 정렬(?) |
52 | - console.log(tweets); | 85 | + console.log(tweets); |
53 | - res.render('popular.html',{timeline: tweets}); | 86 | + res.render('popular.html', { timeline: tweets }); |
54 | - } | 87 | + } |
55 | - | 88 | + else { |
56 | - }); | 89 | + let msg = "" |
57 | - }catch(err){ | 90 | + if (response.statusCode === 404) |
91 | + msg = "User not found." | ||
92 | + else { | ||
93 | + try { | ||
94 | + msg = error[0].message | ||
95 | + } | ||
96 | + catch { | ||
97 | + } | ||
98 | + } | ||
99 | + | ||
100 | + res.render('error.html', { statusCode: response.statusCode, msg: msg }); | ||
101 | + } | ||
102 | + | ||
103 | + }); | ||
104 | + } catch (err) { | ||
58 | console.log(err); | 105 | console.log(err); |
106 | + res.render('error.html', { statusCode: 500, msg: String(err) }); | ||
59 | res.sendStatus(500); | 107 | res.sendStatus(500); |
60 | } | 108 | } |
61 | } | 109 | } | ... | ... |
views/error.html
0 → 100644
1 | +<html lang="en"> | ||
2 | + | ||
3 | + | ||
4 | +<head> | ||
5 | + <meta charset="UTF-8" /> | ||
6 | + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | ||
7 | + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
8 | + <title>Error Page</title> | ||
9 | + <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"> | ||
10 | +</head> | ||
11 | + | ||
12 | + | ||
13 | +<body> | ||
14 | + <div class="d-flex align-items-center justify-content-center vh-100"> | ||
15 | + <div class="text-center"> | ||
16 | + <h1 class="display-1 fw-bold"> | ||
17 | + <%= statusCode %> | ||
18 | + </h1> | ||
19 | + <p class="fs-3"> <span class="text-danger">Opps!</span> Page not found.</p> | ||
20 | + <p class="lead"> | ||
21 | + <%= msg %> | ||
22 | + </p> | ||
23 | + <a href="/" class="btn btn-primary">Go Home</a> | ||
24 | + </div> | ||
25 | + </div> | ||
26 | +</body> | ||
27 | + | ||
28 | + | ||
29 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | <html> | 1 | <html> |
2 | - <head> | 2 | + |
3 | - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> | 3 | +<head> |
4 | - <meta name="viewport" content="width=device-width, initial-scale=1" /> | 4 | + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
5 | - <meta http-equiv="X-UA-Compatible" content="IE=edge" /> | 5 | + <meta name="viewport" content="width=device-width, initial-scale=1" /> |
6 | - <meta name="author" content="colorlib.com"> | 6 | + <meta http-equiv="X-UA-Compatible" content="IE=edge" /> |
7 | - <link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet" /> | 7 | + <meta name="author" content="colorlib.com"> |
8 | - <link href="css/style.css" rel="stylesheet" /> | 8 | + <link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet" /> |
9 | - </head> | 9 | + <link href="css/style.css" rel="stylesheet" /> |
10 | - <body> | 10 | +</head> |
11 | - <div class="s130"> <!--아이디 검색창1 : 계정내 검색--> | 11 | + |
12 | - <form> | 12 | +<body> |
13 | - <div class="inner-form"> | 13 | + <div class="s130"> |
14 | - <div class="input-field first-wrap"> | 14 | + <!--아이디 검색창1 : 계정내 검색--> |
15 | - <div class="svg-wrapper"> | 15 | + <form> |
16 | - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> | 16 | + <div class="inner-form"> |
17 | - <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path> | 17 | + <div class="input-field first-wrap"> |
18 | - </svg> | 18 | + <div class="svg-wrapper"> |
19 | - </div> | 19 | + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> |
20 | - <input id="search1" type="text" placeholder="아이디를 입력하세요" /> | 20 | + <path |
21 | - </div> | 21 | + d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"> |
22 | - <div class="input-field second-wrap"> | 22 | + </path> |
23 | - <button class="btn-search" type="button" onclick="movePage1()">계정 내 검색하기</button> | 23 | + </svg> |
24 | </div> | 24 | </div> |
25 | - <script type ="text/javascript"> | 25 | + <input id="search1" type="text" placeholder="아이디를 입력하세요" /> |
26 | - function movePage1(){ //계정 내 검색 페이지로 이동하기 위한 함수 | 26 | + </div> |
27 | - location.href ="/timeline/"+document.getElementById('search1').value //url을 이렇게 변경함 | 27 | + <div class="input-field second-wrap"> |
28 | - } | 28 | + <button class="btn-search" type="button" onclick="movePage1()">계정 내 검색하기</button> |
29 | - </script> | ||
30 | </div> | 29 | </div> |
30 | + <script type="text/javascript"> | ||
31 | + function movePage1() { //계정 내 검색 페이지로 이동하기 위한 함수 | ||
32 | + location.href = "/timeline/" + document.getElementById('search1').value //url을 이렇게 변경함 | ||
33 | + } | ||
34 | + </script> | ||
35 | + </div> | ||
31 | 36 | ||
32 | - <div class="inner-form"> <!--아이디 검색창2 : 인기글 검색--> | 37 | + <div class="inner-form"> |
33 | - <div class="input-field first-wrap"> | 38 | + <!--아이디 검색창2 : 인기글 검색--> |
34 | - <div class="svg-wrapper"> | 39 | + <div class="input-field first-wrap"> |
35 | - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> | 40 | + <div class="svg-wrapper"> |
36 | - <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path> | 41 | + <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> |
37 | - </svg> | 42 | + <path |
38 | - </div> | 43 | + d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"> |
39 | - <input id="search" type="text" placeholder="아이디를 입력하세요" /> | 44 | + </path> |
45 | + </svg> | ||
40 | </div> | 46 | </div> |
41 | - <div class="input-field second-wrap"> | 47 | + <input id="search" type="text" placeholder="아이디를 입력하세요" /> |
42 | - <button class="btn-search" type="button" onclick="movePage()">인기 게시물 검색하기</button> | 48 | + </div> |
43 | - </div> | 49 | + <div class="input-field second-wrap"> |
44 | - <script type ="text/javascript"> | 50 | + <button class="btn-search" type="button" onclick="movePage()">인기 게시물 검색하기</button> |
45 | - function movePage(){ //인기 게시물 페이지 이동을 위한 함수 | ||
46 | - location.href ="/popular/"+document.getElementById('search').value //url을 이렇게 변경함 | ||
47 | - } | ||
48 | - </script> | ||
49 | </div> | 51 | </div> |
50 | - <span class="info">ex)TwitterKorea </span> | 52 | + <script type="text/javascript"> |
53 | + function movePage() { //인기 게시물 페이지 이동을 위한 함수 | ||
54 | + location.href = "/popular/" + document.getElementById('search').value //url을 이렇게 변경함 | ||
55 | + } | ||
56 | + </script> | ||
57 | + </div> | ||
58 | + <span class="info">ex)TwitterKorea </span> | ||
59 | + | ||
60 | + </form> | ||
61 | + </div> | ||
62 | + <script src="js/extention/choices.js"></script> | ||
63 | +</body><!-- This templates was made by Colorlib (https://colorlib.com) --> | ||
51 | 64 | ||
52 | - </form> | 65 | +</html> |
53 | - </div> | ||
54 | - <script src="js/extention/choices.js"></script> | ||
55 | - </body><!-- This templates was made by Colorlib (https://colorlib.com) --> | ||
56 | -</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | - | ||
2 | <html> | 1 | <html> |
3 | - <head> | 2 | + |
4 | - <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> | 3 | +<head> |
5 | - <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> | 4 | + <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> |
6 | - <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> | 5 | + <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> |
7 | - <!------ Include the above in your HEAD tag ----------> | 6 | + <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> |
8 | - | 7 | + <!------ Include the above in your HEAD tag ----------> |
9 | - | 8 | + |
10 | - <style> | 9 | + |
11 | - #search input[type="text"] { | 10 | + <style> |
12 | - background: url(search-white.png) no-repeat 10px 6px #fcfcfc; | 11 | + #search input[type="text"] { |
13 | - border: 1px solid #d1d1d1; | 12 | + background: url(search-white.png) no-repeat 10px 6px #fcfcfc; |
14 | - font: bold 12px Arial,Helvetica,Sans-serif; | 13 | + border: 1px solid #d1d1d1; |
15 | - color: #bebebe; | 14 | + font: bold 12px Arial, Helvetica, Sans-serif; |
16 | - width: 150px; | 15 | + color: #bebebe; |
17 | - padding: 6px 15px 6px 35px; | 16 | + width: 150px; |
18 | - -webkit-border-radius: 20px; | 17 | + padding: 6px 15px 6px 35px; |
19 | - -moz-border-radius: 20px; | 18 | + -webkit-border-radius: 20px; |
20 | - border-radius: 20px; | 19 | + -moz-border-radius: 20px; |
21 | - text-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); | 20 | + border-radius: 20px; |
22 | - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | 21 | + text-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); |
23 | - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | 22 | + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; |
24 | - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | 23 | + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; |
25 | - -webkit-transition: all 0.7s ease 0s; | 24 | + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; |
26 | - -moz-transition: all 0.7s ease 0s; | 25 | + -webkit-transition: all 0.7s ease 0s; |
27 | - -o-transition: all 0.7s ease 0s; | 26 | + -moz-transition: all 0.7s ease 0s; |
28 | - transition: all 0.7s ease 0s; | 27 | + -o-transition: all 0.7s ease 0s; |
29 | - } | 28 | + transition: all 0.7s ease 0s; |
30 | - | 29 | + } |
31 | - #search input[type="text"]:focus { | 30 | + |
32 | - width: 200px; | 31 | + #search input[type="text"]:focus { |
33 | - } | 32 | + width: 200px; |
34 | - | 33 | + } |
35 | - #search input[type="text"]:focus { | 34 | + |
36 | - width: 200px; | 35 | + #search input[type="text"]:focus { |
37 | - } | 36 | + width: 200px; |
38 | - ul.timeline { | 37 | + } |
39 | - list-style-type: none; | 38 | + |
40 | - position: relative; | 39 | + ul.timeline { |
41 | - } | 40 | + list-style-type: none; |
42 | - ul.timeline:before { | 41 | + position: relative; |
43 | - content: ' '; | 42 | + } |
44 | - background: #d4d9df; | 43 | + |
45 | - display: inline-block; | 44 | + ul.timeline:before { |
46 | - position: absolute; | 45 | + content: ' '; |
47 | - left: 29px; | 46 | + background: #d4d9df; |
48 | - width: 2px; | 47 | + display: inline-block; |
49 | - height: 100%; | 48 | + position: absolute; |
50 | - z-index: 400; | 49 | + left: 29px; |
51 | - } | 50 | + width: 2px; |
52 | - ul.timeline > li { | 51 | + height: 100%; |
53 | - margin: 20px 0; | 52 | + z-index: 400; |
54 | - padding-left: 20px; | 53 | + } |
55 | - } | 54 | + |
56 | - ul.timeline > li:before { | 55 | + ul.timeline>li { |
57 | - content: ' '; | 56 | + margin: 20px 0; |
58 | - background: white; | 57 | + padding-left: 20px; |
59 | - display: inline-block; | 58 | + } |
60 | - position: absolute; | 59 | + |
61 | - border-radius: 50%; | 60 | + ul.timeline>li:before { |
62 | - border: 3px solid #22c0e8; | 61 | + content: ' '; |
63 | - left: 20px; | 62 | + background: white; |
64 | - width: 20px; | 63 | + display: inline-block; |
65 | - height: 20px; | 64 | + position: absolute; |
66 | - z-index: 400; | 65 | + border-radius: 50%; |
67 | - } | 66 | + border: 3px solid #22c0e8; |
68 | - </style> | 67 | + left: 20px; |
69 | - </head> | 68 | + width: 20px; |
69 | + height: 20px; | ||
70 | + z-index: 400; | ||
71 | + } | ||
72 | + </style> | ||
73 | +</head> | ||
70 | 74 | ||
71 | 75 | ||
72 | <body> | 76 | <body> |
... | @@ -76,27 +80,43 @@ | ... | @@ -76,27 +80,43 @@ |
76 | <div class="col-md-6 offset-md-3"> | 80 | <div class="col-md-6 offset-md-3"> |
77 | <h4 style="color:rgb(46, 7, 7); font-weight: bold;">HOT</h4> | 81 | <h4 style="color:rgb(46, 7, 7); font-weight: bold;">HOT</h4> |
78 | <ul class="Timeline"> | 82 | <ul class="Timeline"> |
79 | - <% for (var i=0; i<20; i++){ %> | 83 | + <% for (var i=0; i<timeline.length; i++){ %> |
80 | - <li> | 84 | + <li> |
81 | - <h5 style="color: gold; font-weight: bold;"><%= i + 1 %>위!</h5> | 85 | + <h5 style="color: gold; font-weight: bold;"> |
82 | - <% if(timeline[i].hasOwnProperty('retweeted_status')) { %> <!--내가 다른사람 글을 리트윗한거면 원글을 쓴 사람 닉네임 출력--> | 86 | + <%= i + 1 %>위! |
83 | - <a style ="font-weight: bold;" target="_blank" href=><%= timeline[i].retweeted_status.user.name %></a> | 87 | + </h5> |
84 | - <% } else { %> <!--아니면 내 닉네임--> | 88 | + <% if(timeline[i].hasOwnProperty('retweeted_status')) { %> |
85 | - <a style ="font-weight: bold;" target="_blank" href=><%= timeline[i].user.name %></a> | 89 | + <!--내가 다른사람 글을 리트윗한거면 원글을 쓴 사람 닉네임 출력--> |
86 | - <% } %> | 90 | + <a style="font-weight: bold;" target="_blank" href=> |
87 | - | 91 | + <%= timeline[i].retweeted_status.user.name %> |
88 | - <a href="#" class="float-right"><%= timeline[i].created_at %></a> | 92 | + </a> |
89 | - | 93 | + <% } else { %> |
90 | - <p><%=timeline[i].text%></p> | 94 | + <!--아니면 내 닉네임--> |
91 | - | 95 | + <a style="font-weight: bold;" target="_blank" href=> |
92 | - <% if(timeline[i].hasOwnProperty('extended_entities')) { %> <!--미디어가 존재하면 출력--> | 96 | + <%= timeline[i].user.name %> |
93 | - <img alt="Web Studio" class="img-fluid" width="300" height="300" src= <%= timeline[i].extended_entities.media[0].media_url_https %> /> | 97 | + </a> |
94 | - <% } %> | 98 | + <% } %> |
95 | - | 99 | + |
96 | - <p style="color: #22c0e8;">리트윗: <%= timeline[i].retweet_count %> 마음에 들어요: <%= timeline[i].favorite_count%></p> | 100 | + <a href="#" class="float-right"> |
97 | - </li> | 101 | + <%= timeline[i].created_at %> |
98 | - <% } %> | 102 | + </a> |
99 | - | 103 | + |
104 | + <p> | ||
105 | + <%=timeline[i].text%> | ||
106 | + </p> | ||
107 | + | ||
108 | + <% if(timeline[i].hasOwnProperty('extended_entities')) { %> | ||
109 | + <!--미디어가 존재하면 출력--> | ||
110 | + <img alt="Web Studio" class="img-fluid" width="300" height="300" | ||
111 | + src=<%=timeline[i].extended_entities.media[0].media_url_https %> /> | ||
112 | + <% } %> | ||
113 | + | ||
114 | + <p style="color: #22c0e8;">리트윗: <%= timeline[i].retweet_count %> 마음에 | ||
115 | + 들어요: <%= timeline[i].favorite_count%> | ||
116 | + </p> | ||
117 | + </li> | ||
118 | + <% } %> | ||
119 | + | ||
100 | </ul> | 120 | </ul> |
101 | </div> | 121 | </div> |
102 | </div> | 122 | </div> |
... | @@ -104,4 +124,5 @@ | ... | @@ -104,4 +124,5 @@ |
104 | 124 | ||
105 | 125 | ||
106 | </body> | 126 | </body> |
127 | + | ||
107 | </html> | 128 | </html> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
This diff is collapsed. Click to expand it.
1 | - | ||
2 | <html> | 1 | <html> |
3 | - <head> | ||
4 | - <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> | ||
5 | - <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> | ||
6 | - <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> | ||
7 | - <!------ Include the above in your HEAD tag ----------> | ||
8 | - | ||
9 | - <div style="padding-left: 500px;"> | ||
10 | - <input id = "search1" name="q" type="text" size="40" placeholder="Search..." /> | ||
11 | - <button class="btn-search" type="button" onclick="movePage1()">검색</button> | ||
12 | - <script type ="text/javascript"> | ||
13 | - function movePage1(){ //페이지 이동을 위한 함수 search버튼을 누르면 실행됨 | ||
14 | - location.href =document.location.href +"/"+ document.getElementById('search1').value //url을 이렇게 변경함 | ||
15 | - } | ||
16 | - </script> | ||
17 | - </div> | ||
18 | - <style> | ||
19 | - #search input[type="text"] { | ||
20 | - background: url(search-white.png) no-repeat 10px 6px #fcfcfc; | ||
21 | - border: 1px solid #d1d1d1; | ||
22 | - font: bold 12px Arial,Helvetica,Sans-serif; | ||
23 | - color: #bebebe; | ||
24 | - width: 150px; | ||
25 | - padding: 6px 15px 6px 35px; | ||
26 | - -webkit-border-radius: 20px; | ||
27 | - -moz-border-radius: 20px; | ||
28 | - border-radius: 20px; | ||
29 | - text-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); | ||
30 | - -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | ||
31 | - -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | ||
32 | - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | ||
33 | - -webkit-transition: all 0.7s ease 0s; | ||
34 | - -moz-transition: all 0.7s ease 0s; | ||
35 | - -o-transition: all 0.7s ease 0s; | ||
36 | - transition: all 0.7s ease 0s; | ||
37 | - } | ||
38 | - | ||
39 | - #search input[type="text"]:focus { | ||
40 | - width: 200px; | ||
41 | - } | ||
42 | 2 | ||
43 | - #search input[type="text"]:focus { | 3 | +<head> |
44 | - width: 200px; | 4 | + <link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> |
45 | - } | 5 | + <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> |
46 | - ul.timeline { | 6 | + <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> |
47 | - list-style-type: none; | 7 | + <!------ Include the above in your HEAD tag ----------> |
48 | - position: relative; | 8 | + |
49 | - } | 9 | + <div style="padding-left: 500px;"> |
50 | - ul.timeline:before { | 10 | + <input id="search1" name="q" type="text" size="40" placeholder="Search..." /> |
51 | - content: ' '; | 11 | + <button class="btn-search" type="button" onclick="movePage1()">검색</button> |
52 | - background: #d4d9df; | 12 | + <script type="text/javascript"> |
53 | - display: inline-block; | 13 | + function movePage1() { //페이지 이동을 위한 함수 search버튼을 누르면 실행됨 |
54 | - position: absolute; | 14 | + location.href = document.location.href + "/" + document.getElementById('search1').value //url을 이렇게 변경함 |
55 | - left: 29px; | ||
56 | - width: 2px; | ||
57 | - height: 100%; | ||
58 | - z-index: 400; | ||
59 | - } | ||
60 | - ul.timeline > li { | ||
61 | - margin: 20px 0; | ||
62 | - padding-left: 20px; | ||
63 | - } | ||
64 | - ul.timeline > li:before { | ||
65 | - content: ' '; | ||
66 | - background: white; | ||
67 | - display: inline-block; | ||
68 | - position: absolute; | ||
69 | - border-radius: 50%; | ||
70 | - border: 3px solid #22c0e8; | ||
71 | - left: 20px; | ||
72 | - width: 20px; | ||
73 | - height: 20px; | ||
74 | - z-index: 400; | ||
75 | } | 15 | } |
76 | - </style> | 16 | + </script> |
77 | - </head> | 17 | + </div> |
18 | + <style> | ||
19 | + #search input[type="text"] { | ||
20 | + background: url(search-white.png) no-repeat 10px 6px #fcfcfc; | ||
21 | + border: 1px solid #d1d1d1; | ||
22 | + font: bold 12px Arial, Helvetica, Sans-serif; | ||
23 | + color: #bebebe; | ||
24 | + width: 150px; | ||
25 | + padding: 6px 15px 6px 35px; | ||
26 | + -webkit-border-radius: 20px; | ||
27 | + -moz-border-radius: 20px; | ||
28 | + border-radius: 20px; | ||
29 | + text-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); | ||
30 | + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | ||
31 | + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | ||
32 | + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15) inset; | ||
33 | + -webkit-transition: all 0.7s ease 0s; | ||
34 | + -moz-transition: all 0.7s ease 0s; | ||
35 | + -o-transition: all 0.7s ease 0s; | ||
36 | + transition: all 0.7s ease 0s; | ||
37 | + } | ||
38 | + | ||
39 | + #search input[type="text"]:focus { | ||
40 | + width: 200px; | ||
41 | + } | ||
42 | + | ||
43 | + #search input[type="text"]:focus { | ||
44 | + width: 200px; | ||
45 | + } | ||
46 | + | ||
47 | + ul.timeline { | ||
48 | + list-style-type: none; | ||
49 | + position: relative; | ||
50 | + } | ||
51 | + | ||
52 | + ul.timeline:before { | ||
53 | + content: ' '; | ||
54 | + background: #d4d9df; | ||
55 | + display: inline-block; | ||
56 | + position: absolute; | ||
57 | + left: 29px; | ||
58 | + width: 2px; | ||
59 | + height: 100%; | ||
60 | + z-index: 400; | ||
61 | + } | ||
62 | + | ||
63 | + ul.timeline>li { | ||
64 | + margin: 20px 0; | ||
65 | + padding-left: 20px; | ||
66 | + } | ||
67 | + | ||
68 | + ul.timeline>li:before { | ||
69 | + content: ' '; | ||
70 | + background: white; | ||
71 | + display: inline-block; | ||
72 | + position: absolute; | ||
73 | + border-radius: 50%; | ||
74 | + border: 3px solid #22c0e8; | ||
75 | + left: 20px; | ||
76 | + width: 20px; | ||
77 | + height: 20px; | ||
78 | + z-index: 400; | ||
79 | + } | ||
80 | + </style> | ||
81 | +</head> | ||
78 | 82 | ||
79 | <body> | 83 | <body> |
80 | <div class="container mt-5 mb-5"> | 84 | <div class="container mt-5 mb-5"> |
... | @@ -82,34 +86,52 @@ | ... | @@ -82,34 +86,52 @@ |
82 | <div class="col-md-6 offset-md-3"> | 86 | <div class="col-md-6 offset-md-3"> |
83 | <!--<h4>timeline</h4>--> | 87 | <!--<h4>timeline</h4>--> |
84 | <ul class="Timeline"> | 88 | <ul class="Timeline"> |
85 | - <% for (var i=0; i<20; i++){ %> <!--가져온 타임라인들에 대해서--> | 89 | + <% for (var i=0; i<timeline.length; i++){ %> |
86 | - <li> | 90 | + <!--가져온 타임라인들에 대해서--> |
87 | - <% if(timeline[i].hasOwnProperty('retweeted_status')) { %> <!--내가 다른사람 글을 리트윗한거면 원글을 쓴 사람 닉네임 출력--> | 91 | + <li> |
88 | - <a style ="font-weight: bold;" target="_blank" href=><%= timeline[i].retweeted_status.user.name %></a> | 92 | + <% if(timeline[i].hasOwnProperty('retweeted_status')) { %> |
89 | - <% } else { %> <!--아니면 내 닉네임--> | 93 | + <!--내가 다른사람 글을 리트윗한거면 원글을 쓴 사람 닉네임 출력--> |
90 | - <a style ="font-weight: bold;" target="_blank" href=><%= timeline[i].user.name %></a> | 94 | + <a style="font-weight: bold;" target="_blank" href=> |
91 | - <% } %> | 95 | + <%= timeline[i].retweeted_status.user.name %> |
96 | + </a> | ||
97 | + <% } else { %> | ||
98 | + <!--아니면 내 닉네임--> | ||
99 | + <a style="font-weight: bold;" target="_blank" href=> | ||
100 | + <%= timeline[i].user.name %> | ||
101 | + </a> | ||
102 | + <% } %> | ||
92 | 103 | ||
93 | - <a href="#" class="float-right"><%= timeline[i].created_at %></a> <!--글이 써진 날짜--> | 104 | + <a href="#" class="float-right"> |
105 | + <%= timeline[i].created_at %> | ||
106 | + </a> | ||
107 | + <!--글이 써진 날짜--> | ||
94 | 108 | ||
95 | - <p><%=timeline[i].text%></p> <!--그 글 내용 출력--> | 109 | + <p> |
110 | + <%=timeline[i].text%> | ||
111 | + </p> | ||
112 | + <!--그 글 내용 출력--> | ||
96 | 113 | ||
97 | - <% if(timeline[i].hasOwnProperty('extended_entities')) { %> <!--미디어가 존재하면 출력--> | 114 | + <% if(timeline[i].hasOwnProperty('extended_entities')) { %> |
98 | - <img alt="Web Studio" class="img-fluid" width="300" height="300" src= <%= timeline[i].extended_entities.media[0].media_url_https %> /> | 115 | + <!--미디어가 존재하면 출력--> |
99 | - <% } %> | 116 | + <img alt="Web Studio" class="img-fluid" width="300" height="300" |
117 | + src=<%=timeline[i].extended_entities.media[0].media_url_https %> /> | ||
118 | + <% } %> | ||
100 | 119 | ||
101 | - <p style="color: #22c0e8;">리트윗: <%= timeline[i].retweet_count %> 마음에 들어요: <%= timeline[i].favorite_count%></p> | 120 | + <p style="color: #22c0e8;">리트윗: <%= timeline[i].retweet_count %> 마음에 |
102 | - | 121 | + 들어요: <%= timeline[i].favorite_count%> |
122 | + </p> | ||
123 | + | ||
124 | + | ||
125 | + </li> | ||
126 | + <% } %> | ||
103 | 127 | ||
104 | - </li> | ||
105 | - <% } %> | ||
106 | - | ||
107 | </ul> | 128 | </ul> |
108 | </div> | 129 | </div> |
109 | </div> | 130 | </div> |
110 | </div> | 131 | </div> |
111 | - | 132 | + |
112 | 133 | ||
113 | 134 | ||
114 | </body> | 135 | </body> |
136 | + | ||
115 | </html> | 137 | </html> |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or login to post a comment