Advertisement
Guest User

Untitled

a guest
Dec 31st, 2016
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.46 KB | None | 0 0
  1. #####################################################################
  2. ### Assignment skeleton
  3. ### You can alter the below code to make your own dynamic website.
  4. ### The landing page for assignment 3 should be at /assignment3/
  5. #####################################################################
  6.  
  7. from bottle import route, run, default_app, debug, request
  8. from datetime import date
  9.  
  10. #A fake word coming from round
  11. def Rondo(num): # This is a rounding function I made, it round 6.6 ro 7 and 5.2 to 5
  12. if (num - int(num) >= 0.5):
  13. return int(num) + 1
  14. else:
  15. return int(num)
  16. #Songs
  17. songs = [{ 'name': 'Smells Like Teen Spirit',
  18. 'year': 1991,
  19. 'album': 'Nevermind',
  20. 'band': 'Nirvana',
  21. 'genre': 'Grunge',
  22. 'rating': 5.0,
  23. 'votes': 1},
  24.  
  25. { 'name': 'Welcome to the Jungle',
  26. 'year': 1987,
  27. 'album': 'Appetite for Destruction',
  28. 'band': "Guns N' Roses",
  29. 'genre': 'Hard Rock',
  30. 'rating': 5.0,
  31. 'votes': 1}
  32. ] # This is the list for holding the musics
  33. # User can add to this list in runtime
  34.  
  35. #allowed users
  36. allowedUsers = [
  37. {'username': "VahitOglu", 'password': "polimer"},
  38. {'username': "tnycnsn",'password': "12345"},
  39. {'username': "OmerZade", 'password': "htmlcss"}
  40. ] # This is the list of users who can edit the website
  41. # This is changable in the program but cannot be reached
  42. # from the website. Can be made into a fixed list in the future.
  43.  
  44. posted_comments=[]
  45. # Variable posted_comments i defined. posted_comments will hold comments and users.
  46.  
  47. def htmlify(title, content, style):
  48. page = """<!DOCTYPE html>
  49. <html>
  50. <head>
  51. <meta charset="utf-8" />
  52. <title>""" + title + """</title>""" + style + """
  53. </head>
  54. <body>
  55. """ + content + """
  56. </body>
  57. </html>"""
  58. return page
  59. # Damien's htmlify function, I added the 'style' parameter, for CSS use the below
  60. # function that I made for easy CSS editing.
  61.  
  62. def CSS(): # This is where all styles will be, for clean coding please prevent
  63. # using inline styling as much as you can
  64. css = """<style>
  65. table.music td,th{
  66. border: groove 2px black;
  67. padding: 15px;}
  68. table.music tr{
  69. border-style: groove;}
  70. table.music{
  71. border-collapse: collapse;
  72. border-style: groove;}
  73. table.add td{
  74. padding: 0 15px 0 0;
  75. }
  76. table.music{
  77. border-collapse: collapse;
  78. width: 100%;
  79. height: 100%;
  80. }
  81. table.music td, th{
  82. border: solid 2px black;
  83. padding: 15px;
  84. text-align: center;
  85. }
  86.  
  87. table.comment td, th{
  88. border: solid 2px black;
  89. padding: 15px;
  90. text-align: center;
  91. }
  92.  
  93. table.but{
  94. float: left;
  95. padding: 0 30px 0 0;
  96. }
  97.  
  98. table.but td{
  99. padding: 5px;
  100. }
  101.  
  102. table.inlog{
  103. float: right;
  104. }
  105. .button {
  106. border: solid 2px black;
  107. font-size: 102%;
  108. font-family: arial;
  109. border-radius: 5px;
  110. text-decoration: none;
  111. font-weight: bold;
  112. background-color: #22AABB;
  113. color: #555511;
  114. padding: 0 5px 0 5px;}
  115. th.rate{
  116. color: red;
  117. }
  118. td.rater{
  119. font-size: 10px;
  120. font-weight: bold;
  121. text-align: center;
  122. }
  123.  
  124. .fleft{
  125. float: left;
  126. }
  127. </style>"""
  128. return css
  129. # You know CSS element.{something} means affect the elements of that class
  130. # If there is something like {element}.{class} {element2} then this means
  131. # affect the element2's under element.class
  132.  
  133. def generalError():
  134. content = '<h2 class = "error">There was an error with your submission, please try again.</h2>\n'
  135. content += '<a href = "/assignment3/" class = "button">Return to the list</a>'
  136. return htmlify("Error!", content, CSS())
  137.  
  138. def ValidateUser(username, password):
  139.  
  140. global allowedUsers # As I want to use this list I say I'm using the global list
  141.  
  142. validUser = False # Starts as false
  143.  
  144. for user in allowedUsers:
  145. if (user['username'] == username and user['password'] == password):
  146. validUser = True
  147. # If any of that 3 users are the input to
  148. # username and password boxes then we make validUser True
  149.  
  150. if not validUser: # If the user is not valid, give an error page
  151. userError = "<h1>Your user information is wrong! Please try again.</h1>\n"
  152. userError += """<table>
  153. <tr>
  154. <td><a href = "/assignment3/" class = "button">Return to the list</a></td>
  155. </tr>
  156. </table>"""
  157. return htmlify("There was an error :(", userError, CSS())
  158. return None
  159.  
  160.  
  161. def a3_index(): # This is our index page
  162. indexCont = '<form method = "post" action = "/rate_submit/">\n'
  163. indexCont += '<table class = "music">\n'
  164.  
  165. # If you want to use forms with tables you put the form in one cell or put the
  166. # whole table in a form, otherwise it is not valid. This is what I did.
  167.  
  168. indexCont += "<tr>\n"
  169. indexCont += '<th>Name</th><th>Year</th><th>Album</th><th>Band</th><th>Genre</th><th class="rate">Very Bad</th><th class="rate">Bad</th><th class="rate">Meh</th><th class="rate">Good</th><th class="rate">Very Good!</th>\n'
  170. indexCont += "</tr>\n"
  171. # These are the headers of the table.
  172.  
  173. i = 0
  174. for music in songs:
  175. indexCont += "<tr>\n"
  176. indexCont += "<td>" + music['name'] + "</td>\n"
  177. indexCont += "<td>" + str(music['year']) + "</td>\n"
  178. indexCont += "<td>" + music['album'] + "</td>\n"
  179. indexCont += "<td>" + music['band'] + "</td>\n"
  180. indexCont += "<td>" + music['genre'] + "</td>\n"
  181. indexCont += '<td> <input type="radio" name="rate" value="' + str(i) + '-1"> </td>\n'
  182. indexCont += '<td> <input type="radio" name="rate" value="' + str(i) + '-2"> </td>\n'
  183. indexCont += '<td> <input type="radio" name="rate" value="' + str(i) + '-3"> </td>\n'
  184. indexCont += '<td> <input type="radio" name="rate" value="' + str(i) + '-4"> </td>\n'
  185. indexCont += '<td> <input type="radio" name="rate" value="' + str(i) + '-5"> </td>\n'
  186. indexCont += "</tr>\n"
  187. i += 1
  188. # This for loop prints the songs in the musics list row by row
  189. # i here helps to mark what song is selected if it is the first song and
  190. # 'Very good!' is selected 'rate' will return 0-5 so I will understand
  191. # the first song is selected and got a rating of 5
  192.  
  193. indexCont += "</table>\n"
  194. indexCont += """<table class = "but">
  195. <tr><td><a href = "/add_page/" class = "button">Add a song!</a></td>
  196. <td><a href = "/rating_list/" class = "button">See the ratings</a></td></tr>
  197. <tr><td><a href = "/comments/" class = "button">Add a comment</a></td>
  198. <td><a href = "/comment_list/" class = "button">See the comments</a></td></tr></table>
  199. <table class="inlog">
  200. <tr><td>Username: <input type = "text" name = "username" value = ""></td>
  201. <td>Password: <input type = "password" name = "password" value = ""></td>
  202. <td><input type="submit" value="Rate"></td>
  203. </tr>
  204. </table>
  205. </form>\n"""
  206. # This is the ending of our index page, it contains our buttons and user info
  207.  
  208. return htmlify("My lovely website", indexCont, CSS())
  209.  
  210. def add_page():
  211. addPageContent = """<form method = "post" action = "/add_submit/">
  212. <table class = "add">
  213. <tr><td>Name:</td><td><input type = "text" name = "name" value = ""></td></tr>
  214. <tr><td>Year:</td><td><input type = "number" name = "year" value = ""></td></tr>
  215. <tr><td>Album:</td><td><input type = "text" name = "album" value = ""></td></tr>
  216. <tr><td>Band:</td><td><input type = "text" name = "band" value = ""></td></tr>
  217. <tr><td>Genre:</td><td><input type = "text" name = "genre" value = ""></td></tr></table>
  218. <table>
  219. <tr>
  220. <td>Username: <input type = "text" name = "username" value = ""></td>
  221. <td>Password: <input type = "password" name = "password" value = ""></td>
  222. <td><input type = "submit" value = "Add" class="button"></td>
  223. </tr>
  224. <tr>
  225. <td colspan="3"><a href = "/assignment3/" class = "button">Return to the list</a></td>
  226. </tr>
  227. </table>
  228. </form>
  229. """
  230. return htmlify("Add a song!", addPageContent, CSS())
  231. # add_page is pretty straight forward, it creates forms to get song information
  232. # then when the submit button is clicked it submits the innformation to /add_submit/
  233.  
  234. route ('/add_page/', 'GET', add_page)
  235.  
  236. def add_submit(): # This is the song adding page
  237. musicData = request.POST
  238. # The information from the add_page comes as a POST
  239.  
  240. checker = ValidateUser(str(musicData['username']), str(musicData['password']))
  241. if checker is not None:
  242. return checker
  243.  
  244. # I checked the user information from the start so the other operations are
  245. # not made for nothing, if user is not valid these operations below will not be operated
  246.  
  247. name = str(musicData['name'])
  248.  
  249. if name == "":
  250. return generalError()
  251.  
  252. year = int(musicData['year'])
  253.  
  254. if year < 0 or year > 2017:
  255. return generalError()
  256.  
  257. album = str(musicData['album'])
  258.  
  259. if album == "":
  260. return generalError()
  261.  
  262. band = str(musicData['band'])
  263.  
  264. if band == "":
  265. return generalError()
  266.  
  267. genre = str(musicData['genre'])
  268.  
  269. if genre == "":
  270. return generalError()
  271. # These are the information from the add_page, I get these from the text boxes
  272.  
  273. global songs
  274. songs = songs + [{'name': name, 'year': year, 'album': album, 'band': band, 'genre': genre, 'rating': -1, 'votes': 0}]
  275. # I want to add a song to the musics list so I show I'm using the global to python
  276. # then as you see I am adding a song to the musics, this is the proper way to do it
  277. # I know the rect parantheses may seem odd but it is valid.
  278.  
  279. addSubmitContent = """
  280. <h2>The song below has been added to the list</h2>
  281. <table class = "music">
  282. <tr><th>Name:</th><td>""" + name + """</td></tr>
  283. <tr><th>Year:</th><td>""" + str(year) + """</td></tr>
  284. <tr><th>Album:</th><td>""" + album + """</td></tr>
  285. <tr><th>Band:</th><td>""" + band + """</td></tr>
  286. <tr><th>Genre</th><td>""" + genre + """</td></tr>
  287. <tr><td colspan = "2"><a href = "/assignment3/" class = "button">Return to the list</a></td></tr>
  288. </table>"""
  289. return htmlify("Song successfully added!", addSubmitContent, CSS())
  290. # After all those operations a webpage is shown to tell the user he/she
  291. # successfully added the song
  292.  
  293. route ('/add_submit/', 'POST', add_submit)
  294.  
  295. def rate_submit():
  296.  
  297. global songs
  298. global allowedUsers
  299.  
  300. ratingData = request.POST
  301.  
  302. checker = ValidateUser(str(ratingData['username']), str(ratingData['password']))
  303. if checker is not None:
  304. return checker
  305.  
  306. # Above operations are just as same as the add_submit page
  307. if not 'rate' in ratingData:
  308. return generalError()
  309.  
  310. rawRating = str(ratingData['rate']).split("-")
  311. # 'rate' is the name I give to radioboxes in the main page. When one of them
  312. # is checked and the rate button is clicked I get the value of it in a format of
  313. # {SongNumber}-{SongRating} so if the value is 5-9 6th(YES 6) song of the list is rated 9
  314. songNum = int(rawRating[0])
  315. # I splitted the value of radio so the first part is song number
  316. rating = int(rawRating[1])
  317. # and the second part is the rating
  318. votes = songs[songNum]['votes']
  319. # votes is an attribute of songs which counts how many votes have been given to the song
  320. songs[songNum]['rating'] = (songs[songNum]['rating'] * votes + rating) / (votes + 1)
  321. # This is pretty basic math, the average rating is 3 and I have 30 votes used so
  322. # if I want to add a new vote I multiply 3 * 30 then add my new rating then
  323. # then divide to 31 to get my new rating, and I assing my new rating
  324. songs[songNum]['votes'] += 1 # A vote is used so I increment votes
  325.  
  326. name = str(songs[songNum]['name'])
  327. year = int(songs[songNum]['year'])
  328. album = str(songs[songNum]['album'])
  329. band = str(songs[songNum]['band'])
  330. genre = str(songs[songNum]['genre'])
  331.  
  332. # This is different from the add_submit, I know the songs list number so using that
  333. # I get my song attributes from the global list musics using the songNum
  334.  
  335. rateSubmitContent = """
  336. <h2>You have rated the song below</h2>
  337. <table class = "music">
  338. <tr><th>Name:</th><td>""" + name + """</td></tr>
  339. <tr><th>Year:</th><td>""" + str(year) + """</td></tr>
  340. <tr><th>Album:</th><td>""" + album + """</td></tr>
  341. <tr><th>Band:</th><td>""" + band + """</td></tr>
  342. <tr><th>Genre</th><td>""" + genre + """</td></tr>
  343. <tr><td><a href = "/rating_list/" class = "button">See the ratings</a></td>
  344. <td><a href = "/assignment3/" class = "button">Return to the list</a></td></tr>
  345. </table>"""
  346. return htmlify("You rated a song", rateSubmitContent, CSS())
  347. # Just as in the add_submit page I show what song is rated after all the operations.
  348.  
  349. route ('/rate_submit/', 'POST', rate_submit)
  350.  
  351. def rating_list(): # This is the page where all ratings are seen
  352.  
  353. global songs
  354.  
  355. ratingListContent = '<table class = "music">\n'
  356. ratingListContent += "<tr><th>Name</th><th>Bar</th><th>Rating</th></tr>"
  357. # Created the table and the headers
  358. for song in songs: # This for is printing songs in the list
  359. ratingListContent += "<tr>\n"
  360. ratingListContent += '<td>' + song['name'] + '</td>\n'
  361. ratingListContent += '<td class = "rater">'
  362. # Above code prints the name of the song to first cell
  363. for i in range(100):
  364. if i < Rondo((song['rating'] / 5) * 100):
  365. ratingListContent += "&#x25A0;" # Black Box - Unicde
  366. else:
  367. ratingListContent += "&#x25A1;" # White Box - Unicode
  368. # This for loops creates the rating bars, it makes the rating into %
  369. # then prints black boxes until the % is reached then prints white boxes
  370. ratingListContent += '</td>\n'
  371. ratingListContent += '<td>' + str("{0:.2f}".format(round(song['rating'],2))) + ' / <b>5</b></td>\n'
  372. # This code above prints the rating in the 3rd cell but it rounds 4.3262523 to 4.33
  373. ratingListContent += "</tr>\n"
  374. ratingListContent += '<tr>\n'
  375. ratingListContent += '<td colspan = "3"><a href = "/assignment3/" class = "button">Return to the list</a></td>\n'
  376. ratingListContent += '</tr>\n'
  377. ratingListContent += "</table>"
  378. return htmlify("Ratings", ratingListContent, CSS())
  379. # Lastly buttons are printed and the rating list is done
  380. route ('/rating_list/', 'GET', rating_list)
  381.  
  382. def comments():
  383. # Defining a function to make users able to leave comments.
  384. html="""<h2>Leave a comment to us!</h2>
  385. <form method="post" action="/comment_sent/" id="comment">
  386. <table>
  387. <tr><td colspan="2">Name:</td></tr>
  388. <tr><td colspan="2"><input type="text" name="nick" size="67"></td></tr>
  389. <tr><td colspan="2">Comment:</td></tr>
  390. <tr><td colspan="2"><textarea name="comment" form="comment" rows="7" cols="65"></textarea></td></tr>
  391. <tr>
  392. <td><input type="submit" value="Send your comment" class="button"></td>
  393. <td><a href="/comment_list/" class = "button">Click to see other comments!</a></td>
  394. </tr>
  395. </table>
  396. </form>
  397. """
  398. # <textarea> element creates a text area which provides us to take text inputs with no character boundaries.
  399. # <form> and <textarea> elements are associated with id="comment" and form="comment" attributes and values.(line 382 and 385)
  400. # Data is taken with post method. A link is given to see the other comments.
  401.  
  402. return htmlify("Comments", html, CSS()) # Returning htmlified content.
  403.  
  404. route ('/comments/', 'GET', comments) # Routing...
  405.  
  406. def comment_sent():
  407. # Defining a function to get data with post method.
  408. global posted_comments
  409. # Making variables global to access them in another function.
  410. commentdata = request.POST
  411. # Data is reached.
  412. posted_comments.append({'name': str(commentdata['nick']), 'comment': str(commentdata['comment'])})
  413. # Data is saved.
  414. html="""<h1>Your comment successfully sent!</h1>
  415. <table><tr>
  416. <td><a href="/comment_list/" class = "button">Click to see other comments</a></td>
  417. <td><a href="/assignment3/" class = "button">Click to go to the main page</a></td></tr></table>
  418. """
  419. # Information and links to Home Page and Comment List.
  420. return htmlify("Comment Sent!", html, CSS()) # Returning htmlified content.
  421.  
  422. route ('/comment_sent/', 'POST', comment_sent) # Routing...
  423.  
  424. def comment_list():
  425.  
  426. global posted_comments
  427.  
  428. # Defining a function to list all comments and names.
  429. html="""
  430. <table class = "music">
  431. <tr>
  432. <th>Name/Nickname</th>
  433. <th>Comment</th>
  434. </tr>
  435. """
  436. # A table element is created.
  437. for comment in posted_comments:
  438. html+="""<tr>
  439. <td>""" + comment['name'] + """</td>
  440. <td>""" + comment['comment'] + """</td>
  441. </tr>"""
  442. # Adding comments and names as table data.
  443. html+="""<tr>
  444. <td><a href="/assignment3/" class = "button">Click to go to the main page</a></td>
  445. <td><a href="/comments/" class = "button">Click to add a comment</a></td></tr></table>"""
  446. # End of html content, with a closing tag and two links, one goes to Home Page and one goes to comment adding page.
  447.  
  448. return htmlify("Comment List", html, CSS()) # Returning htmlified content.
  449.  
  450. route('/comment_list/', 'GET', comment_list) # Routing...
  451.  
  452. def recommendation():
  453. # Defining a function to make users able to leave comments.
  454. html="""
  455. <form method="post" action="/recommend/" id="comment">
  456. <input type="checkbox" name="genre1" value="Pop">Pop</p>
  457. <input type="checkbox" name="genre" value="Rock">Rock</p>
  458. <input type="checkbox" name="genre" value="Metal">Metal</p>
  459. <input type="checkbox" name="genre" value="Blues">Blues</p>
  460. <input type="checkbox" name="genre" value="Classical">Classical</p>
  461. <input type="checkbox" name="genre" value="Country">Country</p>
  462. <input type="checkbox" name="genre" value="Folk">Folk</p>
  463. <input type="checkbox" name="genre" value="Jazz">Jazz</p>
  464. <input type="checkbox" name="genre" value="New age">New age</p>
  465. <input type="checkbox" name="genre" value="Reggae">Reggae</p>
  466. </form>
  467. """
  468. return htmlify("recomments", html, CSS()) # Returning htmlified content.
  469. route ('/recommend/', 'Get', recommendation) # Routing...
  470.  
  471.  
  472.  
  473. def website_index():
  474. return htmlify('My lovely homepage',
  475. """
  476. <p><a href="/assignment1/">Click for my assignment 1.</a></p>
  477. <p><a href="/assignment2/">Click for my assignment 2.</a></p>
  478. <p><a href="/assignment3/">Click for my assignment 3.</a></p>
  479. """, '')
  480.  
  481. route('/assignment3/', 'GET', a3_index)
  482. route('/', 'GET', website_index)
  483.  
  484. #####################################################################
  485. ### Don't alter the below code.
  486. ### It allows this website to be hosted on PythonAnywhere
  487. ### OR run on your computer.
  488. #####################################################################
  489.  
  490. # This line makes bottle give nicer error messages
  491. debug(True)
  492. # This line is necessary for running on PythonAnywhere
  493. application = default_app()
  494. # The below code is necessary for running this bottle app standalone on your computer.
  495. if __name__ == "__main__":
  496. run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement