
#routes/dashboard.py import config from bottle import Bottle, redirect from controllers.login import checkLogged import bottle bottle.BaseRequest.MEMFILE_MAX = 1024 * 1024 app = Bottle() @app.route('/') def index(): if checkLogged.call(): from controllers.dashboard import index return index.call() else: redirect('/') @app.route('/logout') def logout(): from controllers.dashboard import logout logout.call() from routes import category app.mount('/category', category.app)
#controllers/dashboard/index.py import config from bottle import template from copy import deepcopy def call(): kdict = deepcopy(config.kdict) kdict['siteLogo'] = 'ទំព័រការផ្សាយ' kdict['route'] = 'index' return template('dashboard/index.tpl', data=kdict)
<!--views/dashboard/index.tpl--> % rebase('base.tpl') <link href="/static/styles/partials/header.css" rel="stylesheet"></link> <script src="/static/scripts/paginate.js"></script> <section class='Head'> <header class='region'> <div class='site-logo'>{{ data['siteLogo'] }}</div> <form action='/dashboard/search' method='post'> <select name="select"> <option>ការផ្សាយ</option> <option>ជំពូក</option> <option>សៀវភៅ</option> <option>អ្នកប្រើប្រាស់</option> </select> <input type='text' name="q" placeholder="Search" required /> <input type="submit" value='បញ្ជូន' /> </form> <div class='logout'><a href='/dashboard/logout'>ចេញក្រៅ</a></div> </header> </section> <link href="/static/styles/partials/body.css" rel="stylesheet"></link> <section class='Body region'> %include('dashboard/menu.tpl') <% if 'index' in data['route']: include('dashboard/post.tpl') elif 'category' in data['route']: include('dashboard/category.tpl') end %> </section> <link href="/static/styles/partials/listing.css" rel="stylesheet"></link> <section class='Listing region'> %if 'count' in data: <div class='info'>Total amount of item: {{data['count']}}</div> %else: <div class='info'>Total amount of item:</div> %end <div class='items'> %if 'items' in data: %for item in data['items']: <div class='item'> <a href="/{{data['route']}}/{{item[3]}}"><img class='thumb' src="{{item[1]}}" /></a> <div class='wrapper'> <a href="/{{data['route']}}/{{item[3]}}">{{item[0]}}</a> <p class='date'></p> <script> $('.items .item .date').html(new Date("{{item[2]}}").toLocaleDateString()) </script> </div> <div class='icon'> <a href='/dashboard/{{data["route"]}}/edit/{{item[3]}}'><img src='/static/images/edit.png' /></a> <a href='/dashboard/{{data["route"]}}/delete/{{item[3]}}'><img src='/static/images/delete.png' /></a> </div> </div> %end %end </div> <script> var route = "{{data['route']}}" </script> <div class='load-more'><img onclick='paginate(route)' src="/static/images/load-more.png" /></div> </section>
<!--views/dashboard/post.tpl--> <link rel='stylesheet' href='/static/styles/post.css' /> <script src="/static/scripts/ckeditor/ckeditor.js"></script> <section class='Main'> <div class='content'> <form action='/users/post' method='post' > <input type='text' name='title' placeholder='ចំណងជើង' required /> <textarea name="content" id="editor" ></textarea> <div class='wrapper'> <select name='category' > <option>categories</option> </select> <input type='text' name='thumb' required placeholder="តំណរភ្ជាប់រូបតំណាង" /> <input type='datetime-local' value='datetime' name='datetime' required /> <input type='submit' value='ចុះផ្សាយ' /> </div> <input name='entries' value='' type='hidden' /> </form> <div class='form'> <select name='type'> <option>YouTube</option> <option>YouTubePlaylist</option> <option>Facebook</option> <option>OK</option> <option>Dailymotion</option> <option>Vimeo</option> </select> <input name='id' type='text' placeholder="អត្តសញ្ញាណវីដេអូ" required /> <select name='ending'> <option>ចប់ហើយ</option> <option>មិនទាន់ចប់</option> </select> <input onclick='genJson()' type="button" value="បញ្ចូលវីដេអូ" /> </div> <table class='viddata'></table> <script src="/static/scripts/ckeditor/config.js"></script> </div> </section>
/*asset/css/post.css*/ .Main .content .ck-editor__editable{ min-height: 350px; color: black; } .Main .content form .wrapper, .Main .content .form{ margin-top:5px; display: grid; grid-template-columns: 20% auto 30% 15%; } .Main .content form input, .Main .content form select, .Main .content .form input, .Main .content .form select { font: var(--body-font); width: 100%; padding: 5px; } table { margin-top: 0px; width: 100%; border-collapse: collapse; } table, td, th { border: 1px solid black; background: white; color: black; text-align: center; padding: 5px; } .Main .content table, th { background: #ddd; } .Main .content table .episode:hover{ cursor: pointer; color: red; } .Main .item{ margin-top: 5px; display: grid; grid-template-columns: 20% auto 20%; grid-gap: 10px; align-items: center; background: var(--background-light); } .Main .item .thumb{ position: relative; padding-top: 56.25% } .Main .item .thumb img{ position: absolute; width: 100%; height: 100%; top: 0; left: 0; } .Main .item .title-date, .Main .item .title-date a{ color: black; } .Main .item .edit-delete{ text-align: right; padding-right: 10px; visibility: hidden; } .Main .item .edit-delete img{ width: 35px; } .Main .item:hover .edit-delete{ visibility: visible; }
GitHub: https://github.com/Sokhavuth/REST-API
Vercel: https://rest-api-zeta.vercel.app