Showing
26 changed files
with
674 additions
and
0 deletions
README.md
0 → 100644
1 | +# 나만의 편성표 - My Personal Broadcating Schedule | ||
2 | +## Description | ||
3 | +- 오픈소스SW개발 프로젝트 | ||
4 | +- 관심있는 인물이 출연하는 방송 프로그램을 검색하여 나만의 편성표를 만든다. | ||
5 | + | ||
6 | +## Environment | ||
7 | +- Backend - Node.js / Express | ||
8 | +- Frontend - HTML5/CSS/Javascript | ||
9 | +- DB - MongoDB | ||
10 | + | ||
11 | +## Prerequisite | ||
12 | +- Terminal Environment | ||
13 | + | ||
14 | +- 1.Clone | ||
15 | +> git clone \<THIS-PROJECT\> | ||
16 | + | ||
17 | +- 2.Install modules | ||
18 | +> cd \<THIS-PROJECT\> | ||
19 | +> npm install | ||
20 | + | ||
21 | +- 3.Run | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/app.js
0 → 100644
1 | +var express = require('express'); | ||
2 | +var app = express(); | ||
3 | +var bodyParser = require('body-parser'); | ||
4 | +var session = require('express-session'); | ||
5 | +var mongoose = require('mongoose'); | ||
6 | +var passport = require('passport'); | ||
7 | + | ||
8 | +//DB연결 | ||
9 | +mongoose.connect('mongodb://username:pwd@host/dbname'); | ||
10 | +mongoose.Promise = global.Promise; | ||
11 | +var db = mongoose.connection; | ||
12 | + | ||
13 | +//연결실패 | ||
14 | +db.on('error', function() | ||
15 | +{ | ||
16 | + console.log('Connection Failed!'); | ||
17 | +}); | ||
18 | + | ||
19 | +//연결 성공 | ||
20 | +db.once('open', function() | ||
21 | +{ | ||
22 | + console.log('Connected!'); | ||
23 | +}); | ||
24 | + | ||
25 | +// DB모델정의 | ||
26 | +var Users = require('./models/users'); | ||
27 | + | ||
28 | +// session | ||
29 | +app.use(session({ | ||
30 | + secret: 'keyboard cat', | ||
31 | + resave: false, | ||
32 | + saveUninitialized: true | ||
33 | +})); | ||
34 | + | ||
35 | +// passport setting | ||
36 | +require('./passport')(passport); | ||
37 | +app.use(passport.initialize()); | ||
38 | +app.use(passport.session()); //로그인 세션 유지 | ||
39 | +// 주의! passport.session을 사용하기 전에 app.use(session(~))설정을 해줘야 한다. | ||
40 | +// 그렇지 않으면 passport가 session을 사용하지 못한다. | ||
41 | +// app.use는 동기식으로 작동하기 때문에 순서에 유의해야한다. | ||
42 | + | ||
43 | + | ||
44 | +// ejs사용 | ||
45 | +// json사용설정 | ||
46 | +app.set('view engine','ejs'); | ||
47 | +app.use(bodyParser.json()); | ||
48 | +app.use(bodyParser.urlencoded({extended: true})); | ||
49 | + | ||
50 | +// router import | ||
51 | +var router = require('./routing')(app, Users); | ||
52 | + | ||
53 | +var server = app.listen(23023, function() | ||
54 | +{ | ||
55 | + var host = server.address().address; | ||
56 | + var port = server.address().port; | ||
57 | + console.log("http://%s:%s",host, port); | ||
58 | +}); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/models/users.js
0 → 100644
1 | +var mongoose = require('mongoose'); | ||
2 | +var bcrypt = require('bcrypt-nodejs'); | ||
3 | + | ||
4 | +var userSchema = mongoose.Schema | ||
5 | +( | ||
6 | + { | ||
7 | + id: String, | ||
8 | + pwd: String, | ||
9 | + name: String | ||
10 | + } | ||
11 | +); | ||
12 | + | ||
13 | +// 패스워드 암호화 | ||
14 | +userSchema.methods.generateHash = function(password) | ||
15 | +{ | ||
16 | + // password hash를 만든다 | ||
17 | + return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null); | ||
18 | +}; | ||
19 | + | ||
20 | +// 패스워드 검증 | ||
21 | +userSchema.methods.validPassword = function(password) | ||
22 | +{ | ||
23 | + // 기존의 해쉬값과 들어온 패스워드를 해쉬값으로 만든 값을 비교한다. | ||
24 | + // 주의! 기존의 값이 해쉬가 아니라면 비교불가. 따라서 에러. | ||
25 | + // 또한 나는 bcrypt를 bcryt로 잘못 썼는데 잘 안보인다... 조심해라... | ||
26 | + //var good = bcrypt.hashSync(this.pwd, bcrypt.genSaltSync(8), null); | ||
27 | + return bcrypt.compareSync(password, this.pwd); | ||
28 | +}; | ||
29 | + | ||
30 | +module.exports = mongoose.model('user',userSchema); | ||
31 | + |
server_db/mongodb_connect.js
0 → 100644
1 | +var mongoose = require('mongoose'); | ||
2 | +mongoose.connect('mongodb://username:pwd@host/dbname'); | ||
3 | +var db = mongoose.connection; | ||
4 | + | ||
5 | +//연결실패 | ||
6 | +db.on('error', function(){ | ||
7 | + console.log('Connection Failed!'); | ||
8 | +}); | ||
9 | +//연결 성공 | ||
10 | +db.once('open', function() { | ||
11 | + console.log('Connected!'); | ||
12 | +}); | ||
13 | + | ||
14 | + | ||
15 | + | ||
16 | +var testSchema = mongoose.Schema | ||
17 | +({ | ||
18 | + name: String | ||
19 | +}); | ||
20 | + | ||
21 | +var TestModel = mongoose.model("TestModel", testSchema); | ||
22 | + | ||
23 | +/* | ||
24 | +var test = new TestModel({ name: "test" }); | ||
25 | + | ||
26 | +test.save(function(err, test) | ||
27 | +{ | ||
28 | + if(err){console.log(err);} | ||
29 | + else{console.log("Success!");} | ||
30 | + console.log("ok4"); | ||
31 | +}); | ||
32 | +*/ | ||
33 | + | ||
34 | +TestModel.find(function(err, test){ | ||
35 | + if(err){console.log(err);} | ||
36 | + else{ | ||
37 | + console.log(test); | ||
38 | + } | ||
39 | +}); | ||
40 | + | ||
41 | + | ||
42 | +db.close() | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/package-lock.json
0 → 100644
This diff is collapsed. Click to expand it.
server_db/package.json
0 → 100644
1 | +{ | ||
2 | + "name": "my-broadcasting-ksw", | ||
3 | + "version": "1.0.0", | ||
4 | + "description": "- 오픈소스SW개발 프로젝트 - 관심있는 인물이 출연하는 방송 프로그램을 검색하여 나만의 편성표를 만든다.", | ||
5 | + "main": "index.js", | ||
6 | + "scripts": { | ||
7 | + "test": "echo \"Error: no test specified\" && exit 1" | ||
8 | + }, | ||
9 | + "repository": { | ||
10 | + "type": "git", | ||
11 | + "url": "http://khuhub.khu.ac.kr/2013104043/my-broadcasting.git" | ||
12 | + }, | ||
13 | + "author": "", | ||
14 | + "license": "ISC", | ||
15 | + "dependencies": { | ||
16 | + "bcrypt-nodejs": "0.0.3", | ||
17 | + "body-parser": "^1.18.3", | ||
18 | + "cheerio": "^1.0.0-rc.2", | ||
19 | + "ejs": "^2.6.1", | ||
20 | + "express": "^4.16.4", | ||
21 | + "express-session": "^1.15.6", | ||
22 | + "iconv": "^2.3.1", | ||
23 | + "mongoose": "^5.3.14", | ||
24 | + "passport": "^0.4.0", | ||
25 | + "passport-local": "^1.0.0", | ||
26 | + "request": "^2.88.0", | ||
27 | + "selenium-webdriver": "^4.0.0-alpha.1" | ||
28 | + } | ||
29 | +} |
server_db/passport.js
0 → 100644
1 | +var LocalStrategy = require('passport-local').Strategy; | ||
2 | +var Users = require('./models/users'); | ||
3 | + | ||
4 | +module.exports = function(passport) | ||
5 | +{ | ||
6 | + passport.serializeUser(function(user, done) | ||
7 | + { | ||
8 | + done(null, user.id); | ||
9 | + }); | ||
10 | + | ||
11 | + passport.deserializeUser(function(id, done) | ||
12 | + { | ||
13 | + done(null, id); | ||
14 | + /* | ||
15 | + Users.findById(id, function(err, user) | ||
16 | + { | ||
17 | + done(err, user); | ||
18 | + }); | ||
19 | + */ | ||
20 | + }); | ||
21 | + | ||
22 | + // 회원가입 처리 | ||
23 | + passport.use('join', new LocalStrategy | ||
24 | + ( | ||
25 | + { | ||
26 | + usernameField: 'id', | ||
27 | + passwordField: 'pwd', | ||
28 | + passReqToCallback: true | ||
29 | + }, | ||
30 | + | ||
31 | + function(req, id, pwd, done) | ||
32 | + { | ||
33 | + Users.findOne({'id':id}, function(err, user) | ||
34 | + { | ||
35 | + if(err) return done(err); | ||
36 | + | ||
37 | + // 유저가 있을 경우 처리 | ||
38 | + if(user) | ||
39 | + { | ||
40 | + console.log("Duplicated user"); | ||
41 | + return done(null, false); | ||
42 | + } | ||
43 | + | ||
44 | + // 새로운 유저 DB추가처리 | ||
45 | + else | ||
46 | + { | ||
47 | + var newUser = new Users(); | ||
48 | + newUser.id = id; | ||
49 | + newUser.pwd = newUser.generateHash(pwd); | ||
50 | + | ||
51 | + // 로그인 이외 필요한 값들 추가 | ||
52 | + newUser.name = req.body.name; | ||
53 | + | ||
54 | + newUser.save(function(err) | ||
55 | + { | ||
56 | + if(err) throw err; | ||
57 | + return done(null, newUser); | ||
58 | + }); | ||
59 | + | ||
60 | + } | ||
61 | + }); | ||
62 | + })); | ||
63 | + | ||
64 | + // 로그인 처리 | ||
65 | + passport.use('login', new LocalStrategy | ||
66 | + ( | ||
67 | + { | ||
68 | + usernameField: 'id', | ||
69 | + passwordField: 'pwd', | ||
70 | + passReqToCallback: true | ||
71 | + }, | ||
72 | + function(req, id, pwd, done) | ||
73 | + { | ||
74 | + Users.findOne({'id': id}, function(err, user) | ||
75 | + { | ||
76 | + if(err) return done(err); | ||
77 | + | ||
78 | + // 유저가 없을 시 | ||
79 | + if(!user) | ||
80 | + { | ||
81 | + console.log('no user'); | ||
82 | + return done(null, false); | ||
83 | + //return done(null, false, req.flash('loginMessage', '없는 유저입니다..')); | ||
84 | + } | ||
85 | + | ||
86 | + // 틀린 비밀번호 | ||
87 | + if(!user.validPassword(pwd)) | ||
88 | + { | ||
89 | + console.log('bad password'); | ||
90 | + return done(null, false); | ||
91 | + //return done(null, false, req.flash('loginMessage', '비밀번호가 다릅니다.')); | ||
92 | + } | ||
93 | + | ||
94 | + console.log('login sucess'); | ||
95 | + return done(null, user); | ||
96 | + }); | ||
97 | + } | ||
98 | + )); | ||
99 | + | ||
100 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/routing.js
0 → 100644
1 | +module.exports = function(app, Users) | ||
2 | +{ | ||
3 | + var passport = require('passport'); | ||
4 | + | ||
5 | + app.get('/', function(req, res) | ||
6 | + { | ||
7 | + // 로그인 중이면 메인페이지로 | ||
8 | + if(req.isAuthenticated()) | ||
9 | + res.redirect("/main"); | ||
10 | + // 로그인 중이 아니라면 인덱스페이지 | ||
11 | + else | ||
12 | + { | ||
13 | + res.render("index"); | ||
14 | + console.log("The index page!"); | ||
15 | + } | ||
16 | + }); | ||
17 | + | ||
18 | + // 로그인 수행 - POST | ||
19 | + app.route('/login') | ||
20 | + .post(passport.authenticate('login', | ||
21 | + { | ||
22 | + successRedirect: '/main', | ||
23 | + failureRedirect: '/' | ||
24 | + //failureFlash : true | ||
25 | + })) | ||
26 | + // unexpected access | ||
27 | + .get(function(req, res) | ||
28 | + { | ||
29 | + res.redirect("/"); | ||
30 | + }); | ||
31 | + | ||
32 | + | ||
33 | + // 로그아웃 수행 | ||
34 | + app.get('/logout', function(req, res) | ||
35 | + { | ||
36 | + req.logout(); | ||
37 | + res.redirect('/'); | ||
38 | + }) | ||
39 | + | ||
40 | + | ||
41 | + // Join | ||
42 | + app.route('/join') | ||
43 | + // 처음 Join화면 랜더 - GET | ||
44 | + .get(function(req, res) | ||
45 | + { | ||
46 | + res.render("join") | ||
47 | + }) | ||
48 | + // 실제 Join 수행 - POST | ||
49 | + .post(passport.authenticate('join', | ||
50 | + { | ||
51 | + successRedirect: '/main', | ||
52 | + failureRedirect: '/', | ||
53 | + //failureFlash : true | ||
54 | + })); | ||
55 | + | ||
56 | + | ||
57 | + // 메인화면 - 로그인 후 기본 검색화면으로 | ||
58 | + app.get('/main', function(req, res) | ||
59 | + { | ||
60 | + // 로그인 중이라면 | ||
61 | + if(req.isAuthenticated()) | ||
62 | + { | ||
63 | + console.log("Logged in page"); | ||
64 | + res.render("main"); | ||
65 | + } | ||
66 | + // 로그인 중이 아니라면 | ||
67 | + else res.redirect("/"); | ||
68 | + | ||
69 | + }); | ||
70 | + | ||
71 | + // 마이페이지 - 로그인 필수 | ||
72 | + app.get('/mypage',function(req, res) | ||
73 | + { | ||
74 | + // 로그인 중이라면 | ||
75 | + if(req.isAuthenticated()) | ||
76 | + { | ||
77 | + // find를 쓰면, 다행으로 반환되기 때문에 결과의 첫번째 요소를 지정하고 해야함 | ||
78 | + // 그래서 하나만을 대상으로 할 때는 보통 findOne을 사용 | ||
79 | + // mongoose로 디비 find는 콜백으로 정의해야함. | ||
80 | + Users.findOne({id: req.user}, function(err, user_info) | ||
81 | + { | ||
82 | + console.log("mypage"); | ||
83 | + res.render("mypage", | ||
84 | + { | ||
85 | + id: user_info.id, | ||
86 | + name: user_info.name | ||
87 | + }); | ||
88 | + }); | ||
89 | + | ||
90 | + } | ||
91 | + // 로그인 중이 아니라면 | ||
92 | + else res.redirect("/"); | ||
93 | + }); | ||
94 | + | ||
95 | + | ||
96 | + // 동명이인 검색 페이지 | ||
97 | + app.get("/samename" ,function(req, res) | ||
98 | + { | ||
99 | + var samename_list = [["강호동", "https://search.pstatic.net/common?type=a&size=60x76&quality=95&src=http://sstatic.naver.net/people/portrait/201304/20130403113314207.jpg"], ["강호동", "https://search.pstatic.net/common?type=a&size=60x76&quality=95&src=http://sstatic.naver.net/people/72/201601061648058211.jpg"]]; | ||
100 | + console.log("samename page"); | ||
101 | + res.render("samename",{samename : samename_list}); | ||
102 | + }); | ||
103 | + | ||
104 | + // 인물-방송정보 페이지 | ||
105 | + app.get("/programs", function(req, res) | ||
106 | + { | ||
107 | + var program_list = | ||
108 | + [ | ||
109 | + ["https://search.pstatic.net/common?type=o&size=120x172&quality=90&direct=true&src=http%3A%2F%2Fsstatic.naver.net%2Fkeypage%2Fimage%2Fdss%2F57%2F03%2F30%2F31%2F57_9033031_poster_image_1543806768348.jpg", | ||
110 | + "2018", | ||
111 | + "아모르파티", | ||
112 | + true, | ||
113 | + "SUN", | ||
114 | + "2240"], | ||
115 | + ["https://search.pstatic.net/common?type=o&size=120x172&quality=90&direct=true&src=http%3A%2F%2Fsstatic.naver.net%2Fkeypage%2Fimage%2Fdss%2F57%2F03%2F30%2F31%2F57_9033031_poster_image_1543806768348.jpg", | ||
116 | + "2018", | ||
117 | + "아모르파티", | ||
118 | + true, | ||
119 | + "SUN", | ||
120 | + "2240"] | ||
121 | + ]; | ||
122 | + res.render("programs", {programs: program_list}); | ||
123 | + }); | ||
124 | + | ||
125 | + // 나만의 시간표 | ||
126 | + app.get("/timetable", function(req, res) | ||
127 | + { | ||
128 | + | ||
129 | + var program_list = | ||
130 | + [ | ||
131 | + { | ||
132 | + content: '런닝맨', | ||
133 | + endDate: new Date(2018, 11, 9, 5, 45), | ||
134 | + startDate: new Date(2018, 11, 9, 1, 30), | ||
135 | + disabled: true | ||
136 | + } | ||
137 | + ]; | ||
138 | + | ||
139 | + res.render("timetable", {pl: JSON.stringify(program_list)}); | ||
140 | + }); | ||
141 | + | ||
142 | +} | ||
143 | + | ||
144 | + | ||
145 | + | ||
146 | + | ||
147 | + | ||
148 | +/* | ||
149 | +(구)직접 DB에 저장하기 | ||
150 | +.post(function(req, res) // 실제 Join 수행 - POST | ||
151 | +{ | ||
152 | + // user정보 입력 | ||
153 | + var user = new Users(); | ||
154 | + user.id = req.body.id; | ||
155 | + user.pwd = req.body.pwd; | ||
156 | + user.name = req.body.name; | ||
157 | + | ||
158 | + // DB저장 | ||
159 | + user.save(function(err) | ||
160 | + { | ||
161 | + if(err) | ||
162 | + { | ||
163 | + console.log(err); | ||
164 | + res.send("Error!") | ||
165 | + } | ||
166 | + else | ||
167 | + { | ||
168 | + console.log("Join Success"); | ||
169 | + res.redirect('/'); | ||
170 | + } | ||
171 | + }); | ||
172 | +}); | ||
173 | +*/ | ||
174 | + | ||
175 | +/* | ||
176 | +(구)직접 로그인 하기 | ||
177 | +app.post('/login', function(req, res) | ||
178 | +{ | ||
179 | + Users.find({id: req.body.id, pwd: req.body.pwd},{_id: 1}, function(err, user) | ||
180 | + { | ||
181 | + if(err) | ||
182 | + { | ||
183 | + console.log("Error!"); | ||
184 | + res.send("Error!") | ||
185 | + } | ||
186 | + | ||
187 | + // 매칭정보 없음 - 로그인 실패 | ||
188 | + if(user.length==0) | ||
189 | + { | ||
190 | + console.log("Login failed!") | ||
191 | + res.send("Login_failed"); | ||
192 | + } | ||
193 | + | ||
194 | + // 매칭정보 있음 - 로그인 성공 | ||
195 | + else | ||
196 | + { | ||
197 | + console.log("Login Success!") | ||
198 | + res.redirect("/main"); | ||
199 | + // main으로 이동 | ||
200 | + } | ||
201 | + }); | ||
202 | +}); | ||
203 | +*/ | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/views/alloyscheulertest.ejs
0 → 100644
1 | + | ||
2 | +<div id="wrapper"> | ||
3 | +<div id="myScheduler"></div> | ||
4 | +</div> | ||
5 | +<script> | ||
6 | + setTimeout(() => | ||
7 | + { | ||
8 | + YUI().use('aui-scheduler', | ||
9 | + function(Y) | ||
10 | + { | ||
11 | + // code goes here | ||
12 | + | ||
13 | + //console.log(<%- pl %>); | ||
14 | + | ||
15 | + var events = | ||
16 | + [ | ||
17 | + { | ||
18 | + content: '<%- pl[0].content%>', | ||
19 | + endDate: new Date(2018, 11, 9, 5, 30), | ||
20 | + startDate: new Date(2018, 11, 9, 1, 30), | ||
21 | + disabled: true | ||
22 | + } | ||
23 | + ]; | ||
24 | + | ||
25 | + var weekView = new Y.SchedulerWeekView(); | ||
26 | + | ||
27 | + myScheduler = new Y.Scheduler( | ||
28 | + { | ||
29 | + boundingBox: '#myScheduler', | ||
30 | + date: new Date(Date.now().getYear, Date.now().getMonth, Date.now().getDay), | ||
31 | + items: events, | ||
32 | + render: true, | ||
33 | + views: [weekView] | ||
34 | + } | ||
35 | + ); | ||
36 | + | ||
37 | + }); | ||
38 | + }, 1000); | ||
39 | +</script> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/views/contents_index.ejs
0 → 100644
1 | +<div class="contents_index"> | ||
2 | + <form method="POST" action="/login"> | ||
3 | + <label>id:</label><input type="text" name="id"><br/> | ||
4 | + <label>pwd:</label><input type="password" name="pwd"><br/> | ||
5 | + <button type="submit">로그인</button> | ||
6 | + </form> | ||
7 | +</div> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/views/contents_join.ejs
0 → 100644
1 | +<div class="contents_index"> | ||
2 | + <form method="POST" action="/join"> | ||
3 | + <label>id:</label><input type="text" name="id"><br/> | ||
4 | + <label>pwd:</label><input type="password" name="pwd"><br/> | ||
5 | + <label>name:</label><input type="text" name="name"><br/> | ||
6 | + <button type="submit">가입</button> | ||
7 | + </form> | ||
8 | + <a href='/'><button>취소</button></a> | ||
9 | +</div> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/views/contents_main.ejs
0 → 100644
server_db/views/contents_mypage.ejs
0 → 100644
server_db/views/contents_programs.ejs
0 → 100644
1 | +<div class="contents_main"> | ||
2 | + <h1>This is Programs</h1> | ||
3 | + <% programs.forEach(function(val){ %> | ||
4 | + <li><img src="<%= val[0]%>"></li> | ||
5 | + <li><%= val[1]%></li> | ||
6 | + <li><%= val[2]%></li> | ||
7 | + | ||
8 | + <% if(val[3] == true) { %> | ||
9 | + <li><%= val[4] %></li> | ||
10 | + <li><%= val[5] %></li> | ||
11 | + <button>추가</button> | ||
12 | + <% } %> | ||
13 | + <% }) %> | ||
14 | +</div> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/views/contents_samename.ejs
0 → 100644
server_db/views/contents_timetable.ejs
0 → 100644
1 | +<div class="contents_main"> | ||
2 | + <h1>This is TimeTable</h1> | ||
3 | + <table border="1"> | ||
4 | + <tr> | ||
5 | + <td>*</td> | ||
6 | + <td>월</td> | ||
7 | + <td>화</td> | ||
8 | + <td>수</td> | ||
9 | + <td>목</td> | ||
10 | + <td>금</td> | ||
11 | + <td>토</td> | ||
12 | + <td>일</td> | ||
13 | + </tr> | ||
14 | + <% for(var i=0; i<=24; i++) { %> | ||
15 | + <tr> | ||
16 | + <td><%=i %></td> | ||
17 | + <% for(var j=1; j<=7; j++) { %> | ||
18 | + <td><%=j %></td> | ||
19 | + <% } %> | ||
20 | + </tr> | ||
21 | + <% } %> | ||
22 | + | ||
23 | + </table> | ||
24 | +</div> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
server_db/views/index.ejs
0 → 100644
server_db/views/join.ejs
0 → 100644
server_db/views/main.ejs
0 → 100644
server_db/views/mypage.ejs
0 → 100644
server_db/views/navigation_index.ejs
0 → 100644
server_db/views/navigation_main.ejs
0 → 100644
server_db/views/programs.ejs
0 → 100644
server_db/views/samename.ejs
0 → 100644
server_db/views/timetable.ejs
0 → 100644
1 | +<html> | ||
2 | +<head> | ||
3 | + <title>My Timetable</title> | ||
4 | + <script src="https://cdn.alloyui.com/3.0.1/aui/aui-min.js"></script> | ||
5 | + <link href="https://cdn.alloyui.com/3.0.1/aui-css/css/bootstrap.min.css" rel="stylesheet"></link> | ||
6 | +</head> | ||
7 | +<body> | ||
8 | + <% include ./navigation_main.ejs %> | ||
9 | + <% include ./alloyscheulertest.ejs %> | ||
10 | +</body> | ||
11 | +</html> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment