├── .bowerrc ├── .gitignore ├── .snyk ├── LICENSE ├── README.md ├── app ├── furion │ ├── app.json │ ├── index.js │ ├── menu.js │ └── readme.md ├── plain │ ├── app.json │ ├── index.js │ ├── menu.js │ └── readme.md └── simplestrap │ ├── app.json │ ├── index.js │ ├── menu.js │ └── page.js ├── bower.json ├── core ├── config │ ├── app_default.json │ ├── database_default.json │ ├── module_list.json │ ├── site_default.json │ └── user_level.json ├── index.js ├── lib │ ├── common.js │ ├── connection.js │ ├── database.js │ ├── dependency.js │ ├── misc.js │ ├── socket.js │ └── theme.js ├── log │ └── log-files-here.txt ├── middleware.js ├── route.js └── setup.js ├── docs ├── blititor_logodesign.ai ├── case_study.md ├── ci.md ├── develop │ ├── convention.md │ ├── menu_path_system.md │ ├── mysql_manage.md │ ├── quick_note.md │ └── windows.md ├── event │ ├── 2016-09-24.md │ ├── 2016-09-25.md │ ├── 2016-09-26.md │ ├── 2016-09-27.md │ ├── 2016-09-28.md │ ├── 2016-09-29.md │ ├── 2016-09-30.md │ └── kosshack2016.md ├── history.md ├── install.md └── tutorial │ ├── asciinema_guide_for_cli.md │ └── video_guide_for_windows_10.md ├── module ├── account │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── account.js │ │ ├── database.js │ │ ├── dummy.json │ │ ├── middleware.js │ │ ├── passport.js │ │ └── query.json │ ├── route.js │ └── route.json ├── administrator │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── administrator.js │ │ ├── database.js │ │ ├── middleware.js │ │ └── query.json │ ├── route.js │ └── route.json ├── app_store │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── appstore.js │ │ ├── database.js │ │ ├── dummy1.json │ │ ├── dummy2.json │ │ ├── middleware.js │ │ └── query.json │ ├── route.js │ └── route.json ├── chatting │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── chatting.js │ │ ├── database.js │ │ ├── middleware.js │ │ └── query.json │ ├── route.js │ └── route.json ├── controller_hub │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── controller_hub.js │ │ ├── database.js │ │ ├── dummy1.json │ │ ├── dummy2.json │ │ ├── dummy3.json │ │ ├── middleware.js │ │ └── query.json │ ├── route.js │ └── route.json ├── counter │ ├── description.md │ ├── index.js │ └── lib │ │ ├── counter.js │ │ ├── database.js │ │ ├── middleware.js │ │ └── query.json ├── editor │ ├── description.md │ └── index.js ├── gallery │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── database.js │ │ ├── gallery.js │ │ ├── middleware.js │ │ └── query.json │ ├── route.js │ └── route.json ├── guestbook │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── database.js │ │ ├── dummy.json │ │ ├── guestbook.js │ │ ├── middleware.js │ │ └── query.json │ ├── route.js │ └── route.json ├── mailgun │ ├── description.md │ ├── index.js │ └── lib │ │ ├── database.js │ │ ├── mailgun.js │ │ └── middleware.js ├── manager │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── database.js │ │ ├── manager.js │ │ ├── middleware.js │ │ └── query.json │ ├── route.js │ └── route.json ├── notice │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── database.js │ │ ├── dummy.json │ │ ├── middleware.js │ │ ├── notice.js │ │ └── query.json │ ├── route.js │ └── route.json ├── reservation │ ├── description.md │ ├── index.js │ ├── lib │ │ ├── database.js │ │ ├── dummy_status.json │ │ ├── manager.js │ │ ├── middleware.js │ │ ├── query.json │ │ └── reservation.js │ ├── route.js │ └── route.json ├── site │ ├── description.md │ ├── index.js │ └── lib │ │ ├── database.js │ │ ├── middleware.js │ │ └── site.js ├── slack │ ├── description.md │ ├── index.js │ └── lib │ │ ├── database.js │ │ ├── middleware.js │ │ └── slack.js └── teamblog │ ├── description.md │ ├── index.js │ ├── lib │ ├── database.js │ ├── dummy.json │ ├── middleware.js │ ├── query.json │ └── teamblog.js │ ├── route.js │ └── route.json ├── package-lock.json ├── package.json ├── public └── common │ └── favicon.ico ├── theme ├── furion │ ├── _include │ │ ├── footer.html │ │ ├── head.html │ │ ├── menu.html │ │ └── menu_item.html │ ├── common │ │ ├── asset │ │ │ ├── andrew-avatar.png │ │ │ ├── ericf-avatar.png │ │ │ ├── reid-avatar.png │ │ │ └── tilo-avatar.png │ │ ├── blog-old-ie.css │ │ ├── blog.css │ │ ├── github-markdown.css │ │ ├── pagination.css │ │ ├── style.css │ │ └── textarea-helper.js │ ├── description.md │ ├── page │ │ ├── _404.html │ │ ├── _500.html │ │ ├── _include │ │ │ └── headed_picture.html │ │ ├── _private.html │ │ ├── account │ │ │ ├── sign_in.html │ │ │ ├── sign_up.html │ │ │ └── user_info.html │ │ ├── index.html │ │ └── teamblog │ │ │ ├── list.html │ │ │ ├── view.html │ │ │ └── write.html │ └── screenshot.jpg ├── plain │ ├── _include │ │ ├── footer.html │ │ ├── header.html │ │ ├── header_item.html │ │ ├── style.html │ │ └── sub_section.html │ ├── admin │ │ ├── _include │ │ │ ├── check.html │ │ │ ├── header.html │ │ │ └── style.html │ │ ├── account.html │ │ ├── account_form.html │ │ ├── index.html │ │ ├── login.html │ │ └── sign_up.html │ ├── common │ │ ├── asset │ │ │ ├── blititor_logo.png │ │ │ ├── blititor_new_logo.png │ │ │ ├── blititor_new_logo_white.png │ │ │ ├── cd-icon-arrow-1.svg │ │ │ ├── cd-icon-arrow-2.svg │ │ │ └── photo-user1.png │ │ ├── chat.js │ │ ├── datepicker.min.css │ │ ├── datepicker.min.js │ │ ├── jquery.bpopup.min.js │ │ ├── pagination.css │ │ ├── plain.css │ │ ├── plain.js │ │ └── style.css │ ├── description.md │ ├── manage │ │ ├── _include │ │ │ ├── header.html │ │ │ └── style.html │ │ ├── account.html │ │ ├── account_counter.html │ │ ├── index.html │ │ ├── login.html │ │ └── page_log.html │ ├── page │ │ ├── _404.html │ │ ├── _500.html │ │ ├── about.html │ │ ├── account │ │ │ ├── sign_in.html │ │ │ └── user_info.html │ │ ├── chatting.html │ │ ├── index.html │ │ ├── marketing.html │ │ └── professional.html │ └── screenshot.jpg ├── simplestrap │ ├── admin │ │ └── index.html │ ├── common │ │ ├── asset │ │ │ ├── blititor_logo.png │ │ │ └── photo-user1.png │ │ ├── github-markdown.css │ │ ├── script.js │ │ └── style.css │ ├── description.md │ ├── manage │ │ └── index.html │ ├── page │ │ ├── _404.html │ │ ├── _500.html │ │ ├── _include │ │ │ ├── flash.html │ │ │ ├── footer.html │ │ │ ├── header.html │ │ │ ├── menu.html │ │ │ └── menu_item.html │ │ ├── _private.html │ │ ├── about.html │ │ ├── account │ │ │ ├── sign_in.html │ │ │ ├── sign_up.html │ │ │ └── user_info.html │ │ ├── guestbook │ │ │ └── guestbook.html │ │ ├── index.html │ │ └── teamblog │ │ │ ├── list.html │ │ │ └── write.html │ ├── screenshot.jpg │ ├── screenshot2.jpg │ ├── screenshot3.jpg │ └── setup │ │ ├── _include │ │ ├── footer.html │ │ └── header.html │ │ ├── _partial │ │ ├── setup-database-done.html │ │ ├── setup-database-error.html │ │ └── setup-database-table-done.html │ │ ├── setup-database-table.html │ │ ├── setup-database.html │ │ ├── setup-theme.html │ │ ├── setup.css │ │ └── setup.js ├── status404.html └── status500.html └── todo.md /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "public/lib", 3 | "json": "bower.json" 4 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | *.seed 4 | *.log 5 | *.csv 6 | *.dat 7 | *.out 8 | *.pid 9 | *.gz 10 | 11 | .idea 12 | .vscode 13 | node_modules 14 | public/lib 15 | public/upload 16 | etc 17 | 18 | npm-debug.log 19 | database.json 20 | database.json.* 21 | theme.json 22 | theme.json.* 23 | config*.json 24 | config*.json.* 25 | 26 | *.psd 27 | *.pxd 28 | 29 | # for commercial themes or modules here. 30 | # or use start string with underbar 31 | # like `c_commercialcompany` 32 | # like `m_marketproduction` 33 | # like `e_enterprisesolution` 34 | app/c_** 35 | theme/c_** 36 | -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.12.0 3 | ignore: {} 4 | patch: {} 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Aiden 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | blititor 2 | ======== 3 | 4 | 5 | Easy to custom for the all Web Agencies and Web Masters in Korea 6 | 7 | > This code is really easy to customize for your business! - Web developer journal in korean times 8 | 9 | ![blititor_logo_nodejsstyle7](https://cloud.githubusercontent.com/assets/22411481/18962436/cd87572a-86ab-11e6-8e6b-d145b325e119.png) 10 | 11 | (a logo presented by Hyejin Lee @melthleeth) 12 | 13 | ![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fsoomtong%2Fblititor.svg?type=shield) 14 | 15 | ## Stack 16 | 17 | - NodeJS + MysqlDB(MariaDB) + Nginx(Caddy) + Sphinx 18 | - Express.js + Socket.io 19 | - Nunjucks html template 20 | - Jquery and many frontend frameworks 21 | - and wonderful NPM 22 | 23 | ## Development 24 | 25 | - [quick note](docs/develop/quick_note.md) 26 | - [convention](docs/develop/convention.md) 27 | - [mysql manage](docs/develop/mysql_manage.md) 28 | - [menu path system](docs/develop/menu_path_system.md) 29 | 30 | ## Demo 31 | 32 | check out the samples! based awesome css frameworks 33 | 34 | - pure 35 | - bulma 36 | - bootstrap 37 | - foundation 38 | - materialize 39 | - kube 40 | - ... 41 | 42 | ## Usage 43 | 44 | prepare git, nodejs, npm, bower 45 | 46 | ### clone repos 47 | 48 | ```shell 49 | git clone git://github.com/soomtong/blititor.git 50 | ``` 51 | 52 | ### install component with npm and bower 53 | 54 | ```shell 55 | npm install 56 | bower install 57 | ``` 58 | 59 | ### create module_list.json 60 | 61 | ```shell 62 | node core/setup.js module 63 | ``` 64 | 65 | ### database configuration (mysql, mariadb) 66 | 67 | ```shell 68 | node core/setup.js db 69 | ``` 70 | 71 | ### make database tables for blititor 72 | 73 | ```shell 74 | node core/setup.js db-init 75 | ``` 76 | 77 | for preparing non-core modules ('guestbook' or 'teamblog'...) 78 | 79 | ```shell 80 | node core/setup.js db-init some_module_name 81 | ``` 82 | 83 | ### make theme configuration 84 | 85 | ```shell 86 | node core/setup.js theme 87 | ``` 88 | 89 | ### make admin account 90 | 91 | ```shell 92 | node core/setup.js admin 93 | ``` 94 | 95 | ### run node app 96 | 97 | ```shell 98 | node core/index 99 | ``` 100 | 101 | or u can override default port using option `port` or `p` 102 | 103 | ``` 104 | node core/index -port=3000 105 | node core/index -p 3000 106 | ``` 107 | 108 | or run dev mode using nodemon 109 | 110 | ``` 111 | npm run dev 112 | ``` 113 | 114 | ## License 115 | 116 | Blititor has MIT License basically. but each theme design license depends on each maker's opinions. 117 | 118 | it will be described each `app` and `theme`'s readme file or description file. 119 | 120 | ![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fsoomtong%2Fblititor.svg?type=large) -------------------------------------------------------------------------------- /app/furion/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "locals": { 3 | "title": "팀블로그" 4 | }, 5 | "config": { 6 | "modules": [], 7 | "vendors": ["pure", "jquery"], 8 | "admin": true, 9 | "manage": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/furion/index.js: -------------------------------------------------------------------------------- 1 | // load packages 2 | var express = require('express'); 3 | 4 | // load cores 5 | var misc = require('../../core/lib/misc'); 6 | 7 | // load modules 8 | var Site = require('../../module/site'); 9 | var Teamblog = require('../../module/teamblog'); 10 | var Account = require('../../module/account'); 11 | 12 | // load locals 13 | var app = require('./app.json'); 14 | var menu = require('./menu'); 15 | 16 | // init 17 | var router = express.Router(); 18 | var routeTable = misc.getRouteData(); 19 | var appLocals = Site.exposeAppLocals(app.locals, menu); 20 | 21 | // middleware 22 | router.use(Account.middleware.exposeLocals); 23 | 24 | // bind static page 25 | router.all(routeTable.root, Teamblog.index); 26 | router.all('/about', Site.redirect(routeTable.root)); 27 | 28 | // bind module 29 | router.use('/account', Account.site); 30 | router.use('/blog', Teamblog.route); 31 | 32 | module.exports = { 33 | config: app.config, 34 | exposeLocals: appLocals, 35 | router: router, 36 | }; 37 | -------------------------------------------------------------------------------- /app/furion/menu.js: -------------------------------------------------------------------------------- 1 | var misc = require('../../core/lib/misc'); 2 | 3 | var routeTable = misc.getRouteData(); 4 | // var routeTable = require('../../core/config/route_default'); 5 | // or sometime need to make your own routeTable 6 | // and update own route table 7 | 8 | // static page menu describe here 9 | // these links are not included modules route paths 10 | var SiteMenu = [ 11 | { 12 | id: 'post_new', 13 | name: '새글', 14 | logged: 1, 15 | level: 2, grant: 'AMC', 16 | url: '/blog' + routeTable.teamblog.write 17 | }, 18 | { 19 | id: 'sign_in', 20 | name: '로그인', 21 | logged: -1, 22 | url: '/account' + routeTable.account.signIn 23 | }, 24 | { 25 | id: 'sign_out', 26 | name: '로그아웃', 27 | logged: 1, 28 | url: '/account' + routeTable.account.signOut 29 | }, 30 | { 31 | id: 'manage', 32 | name: '관리', 33 | logged: 1, 34 | level: 2, grant: 'AMC', 35 | url: '/manage' 36 | }, 37 | { 38 | id: 'about', 39 | name: '소개', 40 | logged: -1, 41 | url: '/about' 42 | } 43 | ]; 44 | 45 | var AdminMenu = [ 46 | { 47 | id: 'index', 48 | name: '관리자 홈', 49 | url: '/admin' 50 | }, 51 | { 52 | id: 'new', 53 | name: '신규 계정 생성', 54 | url: '/admin' + routeTable.admin.account_new 55 | }, 56 | { 57 | id: 'manage', 58 | name: '운영', 59 | url: '/manage' 60 | } 61 | ]; 62 | 63 | var ManageMenu = [ 64 | { 65 | id: 'index', 66 | name: '운영자 홈', 67 | url: '/manage' 68 | }, 69 | { 70 | id: 'account', 71 | name: '계정', 72 | url: '/manage' + routeTable.manage.account 73 | }, 74 | { 75 | id: 'page_log', 76 | name: '페이지 로그', 77 | url: '/manage' + routeTable.manage.page_log 78 | }, 79 | { 80 | id: 'admin', 81 | name: '관리', 82 | url: '/admin' 83 | } 84 | ]; 85 | 86 | module.exports = { 87 | SiteMenu: SiteMenu, 88 | AdminMenu: AdminMenu, 89 | ManageMenu: ManageMenu, 90 | }; -------------------------------------------------------------------------------- /app/furion/readme.md: -------------------------------------------------------------------------------- 1 | ## A real world blog application 2 | 3 | based on plain and pure css framework and their sample 4 | 5 | - multi user author 6 | - tag support 7 | - categorize by monthly 8 | - custom title url (like hacks.mozilla) 9 | - dropbox paper like online editor (hybrid) 10 | - support in-memory image copying in editor 11 | - easy import and embedding images and videos, even audio resource 12 | - image resizer 13 | - smart image placer in post list with flag system 14 | - version history for each posts 15 | - bind related posts (can select other posts in searched list) 16 | - manage own post by each owner 17 | - administrator for manage account 18 | - full text search 19 | 20 | ### Tutorial 21 | 22 | 1. make app folder 23 | 2. prepare index, menu, route file 24 | 3. make app's theme folder 25 | 4. prepare html files and another assets 26 | 5. change values in theme.json 27 | 6. assign some static page 28 | 7. assign some modules method. like a sign in feature 29 | 8. combine other modules in app's router 30 | 31 | ### History 32 | 33 | - 1.0.0: initial release 34 | 35 | ### Credit 36 | 37 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /app/plain/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "locals": { 3 | "title": "Plain" 4 | }, 5 | "config": { 6 | "modules": [], 7 | "vendors": ["pure", "jquery"], 8 | "admin": true, 9 | "manage": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/plain/index.js: -------------------------------------------------------------------------------- 1 | // load packages 2 | var express = require('express'); 3 | 4 | // load cores 5 | var misc = require('../../core/lib/misc'); 6 | 7 | // load modules 8 | var Chat = require('../../module/chatting'); 9 | var Account = require('../../module/account'); 10 | var Site = require('../../module/site'); 11 | 12 | // load locals 13 | var app = require('./app.json'); 14 | var menu = require('./menu'); 15 | 16 | // init 17 | var router = express.Router(); 18 | var routeTable = misc.getRouteData(); 19 | var appLocals = Site.exposeAppLocals(app.locals, menu); 20 | 21 | // middleware 22 | router.use(Account.middleware.exposeLocals); 23 | 24 | // route 25 | router.use('/account', Account.site); 26 | router.post('/account' + routeTable.account.registerSimple, Account.middleware.checkLoggedSession, Account.registerSimple); 27 | router.post('/account' + routeTable.account.add, Account.registerSimple); 28 | 29 | router.use('/chat', Chat.route); 30 | 31 | // init socket.io 32 | Chat.initSocket(BLITITOR._socketIO); 33 | 34 | // bind static page 35 | Site.bindMenu(menu, router); 36 | 37 | module.exports = { 38 | config: app.config, 39 | exposeLocals: appLocals, 40 | router: router, 41 | }; 42 | -------------------------------------------------------------------------------- /app/plain/menu.js: -------------------------------------------------------------------------------- 1 | var misc = require('../../core/lib/misc'); 2 | 3 | var routeTable = misc.getRouteData(); 4 | // var routeTable = require('../../core/config/route_default'); 5 | // or sometime need to make your own routeTable 6 | // and update own route table 7 | 8 | var SiteMenu = [ 9 | { 10 | id: 'index', 11 | name: '홈!!', 12 | logged: -1, 13 | url: routeTable.root 14 | }, 15 | { 16 | id: 'marketing', 17 | name: '마케팅', 18 | logged: -1, 19 | url: '/marketing' 20 | }, 21 | { 22 | id: 'chatting', 23 | name: '채팅', 24 | logged: 1, 25 | url: '/chat' + routeTable.chat.form 26 | }, 27 | { 28 | id: 'professional', 29 | name: '맴버', 30 | logged: -1, 31 | url: '/marketing/professional' 32 | }, 33 | { 34 | id: 'about', 35 | name: '소개', 36 | logged: -1, 37 | url: '/about' 38 | }, 39 | { 40 | id: 'login', 41 | name: '로그인', 42 | logged: -1, 43 | url: '/account' + routeTable.account.signIn 44 | } 45 | ]; 46 | 47 | var AdminMenu = [ 48 | { 49 | id: 'index', 50 | name: '관리자 홈', 51 | url: '/admin' 52 | }, 53 | { 54 | id: 'new', 55 | name: '신규 계정 생성', 56 | url: '/admin' + routeTable.admin.account_new 57 | }, 58 | { 59 | id: 'manage', 60 | name: '운영', 61 | url: '/manage' 62 | } 63 | ]; 64 | 65 | var ManageMenu = [ 66 | { 67 | id: 'index', 68 | name: '운영자 홈', 69 | url: '/manage' 70 | }, 71 | { 72 | id: 'account', 73 | name: '계정', 74 | url: '/manage' + routeTable.manage.account 75 | }, 76 | { 77 | id: 'page_log', 78 | name: '페이지 로그', 79 | url: '/manage' + routeTable.manage.page_log 80 | }, 81 | { 82 | id: 'admin', 83 | name: '관리', 84 | url: '/admin' 85 | } 86 | ]; 87 | 88 | module.exports = { 89 | SiteMenu: SiteMenu, 90 | AdminMenu: AdminMenu, 91 | ManageMenu: ManageMenu, 92 | }; -------------------------------------------------------------------------------- /app/plain/readme.md: -------------------------------------------------------------------------------- 1 | ## A simple demo pages 2 | 3 | just use normal html pages with introduce some features for administrators and managers 4 | 5 | ### Nginx location proxy for prefixed url 6 | 7 | use specified url for location module then confirm the end of location '/' 8 | 9 | `/` == `host:post/` pattern is same to 10 | `/plain/` == `host:post/` pattern 11 | 12 | ``` 13 | 100 server { 14 | 101 server_name demo.blititor.com; 15 | 102 16 | 103 client_body_in_file_only clean; 17 | 104 client_body_buffer_size 32K; 18 | 105 19 | 106 client_max_body_size 20M; 20 | 107 21 | 108 sendfile on; 22 | 109 send_timeout 300s; 23 | 110 24 | 111 location /plain/ { 25 | 112 proxy_set_header X-Real-IP $remote_addr; 26 | 113 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 27 | 114 proxy_set_header Host $http_host; 28 | 115 proxy_set_header X-NginX-Proxy true; 29 | 116 proxy_pass http://127.0.0.1:3011/; 30 | 117 proxy_redirect off; 31 | 118 } 32 | 119 } 33 | ``` 34 | 35 | ### History 36 | 37 | - 1.0.0: initial release 38 | 39 | ### Credit 40 | 41 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /app/simplestrap/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "locals": { 3 | "title": "Simplestrap" 4 | }, 5 | "config": { 6 | "modules": [], 7 | "vendors": ["bootstrap", "jquery"], 8 | "admin": true, 9 | "manage": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /app/simplestrap/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var winston = require('winston'); 3 | 4 | var misc = require('../../core/lib/misc'); 5 | var middleware = require('../../core/middleware'); 6 | 7 | // load modules for router 8 | var Site = require('../../module/site'); 9 | var Account = require('../../module/account'); 10 | var Guestbook = require('../../module/guestbook'); 11 | var Teamblog = require('../../module/teamblog'); 12 | var Editor = require('../../module/editor'); 13 | 14 | // load locals 15 | var app = require('./app.json'); 16 | var menu = require('./menu'); 17 | var page = require('./page'); 18 | 19 | // init 20 | var router = express.Router(); 21 | var routeTable = misc.getRouteData(); 22 | var appLocals = Site.exposeAppLocals(app.locals, menu); 23 | 24 | // middleware 25 | router.use(Account.middleware.exposeLocals); 26 | 27 | // separated page 28 | router.all(routeTable.root, [middleware.test1, middleware.test2], page.indexPage); 29 | 30 | // bind module 31 | router.use('/account', Account.site); 32 | router.use('/guest', Guestbook.route); 33 | router.use('/blog', Teamblog.route); 34 | router.use('/lib', Editor.route); //todo: for test at this time 35 | 36 | // bind static page 37 | Site.bindMenu(menu, router); 38 | 39 | module.exports = { 40 | config: app.config, 41 | exposeLocals: appLocals, 42 | router: router, 43 | }; 44 | -------------------------------------------------------------------------------- /app/simplestrap/menu.js: -------------------------------------------------------------------------------- 1 | var misc = require('../../core/lib/misc'); 2 | 3 | var routeTable = misc.getRouteData(); 4 | 5 | var SiteMenu = [ 6 | { 7 | id: 'index', 8 | name: '홈', 9 | url: routeTable.root 10 | }, 11 | { 12 | id: 'blog', 13 | name: '팀 블로그', 14 | url: '/blog' 15 | }, 16 | { 17 | id: 'guestbook', 18 | name: '방명록', 19 | url: '/guest' 20 | }, 21 | { 22 | id: 'about', 23 | name: '소개', 24 | url: '/about' 25 | }, 26 | { 27 | name: '새글쓰기', 28 | logged: 1, 29 | level: 2, grant: 'AMC', 30 | url: '/blog/write' 31 | }, 32 | { 33 | name: '로그인', 34 | logged: -1, 35 | url: '/account' + routeTable.account.signIn 36 | }, 37 | { 38 | name: '가입하기', 39 | logged: -1, 40 | url: '/account' + routeTable.account.signUp 41 | }, 42 | { 43 | name: '로그아웃', 44 | logged: 1, 45 | url: '/account' + routeTable.account.signOut 46 | } 47 | ]; 48 | 49 | var AdminMenu = {}; 50 | var ManageMenu = {}; 51 | 52 | module.exports = { 53 | SiteMenu: SiteMenu, 54 | AdminMenu: AdminMenu, 55 | ManageMenu: ManageMenu, 56 | }; -------------------------------------------------------------------------------- /app/simplestrap/page.js: -------------------------------------------------------------------------------- 1 | var Teamblog = require('../../module/teamblog/index'); 2 | var common = require('../../core/lib/common'); 3 | 4 | function indexPage(req, res) { 5 | var params = { 6 | title: "Home", 7 | recentPostCount: 4, 8 | recentPostList: [] 9 | }; 10 | 11 | // load recent articles 12 | Teamblog.recentPost(params, function (error, results) { 13 | if (!error) { 14 | results.map(function (item) { 15 | params.recentPostList.push({ 16 | title: item['title'], 17 | preview: common.getHeaderTextFromMarkdown(item['content'], 200) 18 | }); 19 | }); 20 | } 21 | 22 | res.render(BLITITOR.site.theme + '/page/index', params); 23 | }); 24 | } 25 | 26 | module.exports = { 27 | indexPage: indexPage 28 | }; -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blititer", 3 | "version": "0.5.0", 4 | "ignore": [ 5 | ".jshintrc", 6 | "**/*.txt" 7 | ], 8 | "dependencies": { 9 | "jwerty": "~0.3.2", 10 | "blueimp-file-upload": "^9.12.5", 11 | "dragula.js": "dragula#^3.7.2", 12 | "jquery.typist": "^0.0.7", 13 | "markdown-it": "^8.3.1" 14 | }, 15 | "devDependencies": {} 16 | } 17 | -------------------------------------------------------------------------------- /core/config/app_default.json: -------------------------------------------------------------------------------- 1 | { 2 | "locale": "ko", 3 | "logLevel": "debug", 4 | "configFile": "config.json", 5 | "cookieSecret": "blititor", 6 | "sessionSecret": "blititor", 7 | "cacheControl": false 8 | } -------------------------------------------------------------------------------- /core/config/database_default.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 3306, 3 | "database": "db_blititor", 4 | "prefix": "b_" 5 | } -------------------------------------------------------------------------------- /core/config/site_default.json: -------------------------------------------------------------------------------- 1 | { 2 | "port": 3010, 3 | "title": "Blititor", 4 | "url_prefix": "", 5 | "theme": "plain" 6 | } 7 | -------------------------------------------------------------------------------- /core/config/user_level.json: -------------------------------------------------------------------------------- 1 | { 2 | "siteAdmin": "A", 3 | "siteManager": "M", 4 | "contentManager": "C", 5 | "userLevel_1": "1", 6 | "userLevel_2": "2", 7 | "userLevel_3": "3", 8 | "userLevel_4": "4", 9 | "userLevel_5": "5", 10 | "userLevel_6": "6", 11 | "userLevel_7": "7", 12 | "userLevel_8": "8", 13 | "userLevel_9": "9" 14 | } 15 | -------------------------------------------------------------------------------- /core/lib/database.js: -------------------------------------------------------------------------------- 1 | function createDatabase(connection, dbName, callback) { 2 | console.log(' = Make database...'); 3 | 4 | // make database by given name 5 | var sql = 'CREATE DATABASE IF NOT EXISTS ?? DEFAULT CHARACTER SET = ??'; 6 | connection.query(sql, [dbName, 'utf8'], function (err, results) { 7 | 8 | // if has argument then execute callback 9 | if (callback && typeof callback === 'function') callback(err, results); 10 | }); 11 | } 12 | 13 | module.exports = { 14 | createDatabase: createDatabase, 15 | }; -------------------------------------------------------------------------------- /core/lib/dependency.js: -------------------------------------------------------------------------------- 1 | // referenced https://github.com/TryGhost/Ghost/core/server/utils/startup-check.js 2 | var packages = require('../../package.json'); 3 | 4 | function moduleInstalled(env) { 5 | console.info('=== received environment variable ...', env, 'mode'); 6 | console.info('=== check module dependency ...', Object.keys(packages['dependencies']).length, 'packages'); 7 | 8 | if (env !== 'production' && env !== 'development') return; 9 | 10 | var errors = []; 11 | var exceptions = ['font-awesome']; // fa v4 npm has no main entry. it can't resolve 12 | 13 | Object.keys(packages['dependencies']).forEach(function (p) { 14 | try { 15 | if (!exceptions.includes(p)) { 16 | require.resolve(p); 17 | } 18 | } catch (e) { 19 | errors.push(e.message); 20 | } 21 | }); 22 | 23 | if (!errors.length) return; 24 | 25 | errors = errors.join('\n '); 26 | 27 | console.error('\x1B[31mERROR: Blititor is unable to start due to missing dependencies:\033[0m\n ' + errors); 28 | console.error('\x1B[32m\nPlease run `npm install --production` and try starting Blititor again.'); 29 | 30 | process.exit(0); 31 | } 32 | 33 | function nodeVersion() { 34 | console.info('=== check node engine version ...', process['versions'].node); 35 | try { 36 | var semver = require('semver'); 37 | if (!semver.satisfies(process['versions'].node, packages.engines.node) && 38 | !semver.satisfies(process['versions'].node, packages.engines['iojs'])) { 39 | console.error('\x1B[31mERROR: Unsupported version of Node'); 40 | console.error('\x1B[31mBlititor needs Node version ' + packages.engines.node + 41 | ' you are using version ' + process['versions'].node + '\033[0m\n'); 42 | console.error('\x1B[32mPlease go to http://nodejs.org to get a supported version\033[0m'); 43 | 44 | process.exit(0); 45 | } 46 | } catch (e) { 47 | if (e) { 48 | console.error('\x1B[31mERROR: Unsupported version of Node'); 49 | } 50 | } 51 | } 52 | 53 | function appConfig() { 54 | try { 55 | require('../config/app_default.json'); 56 | } catch (e) { 57 | console.error('app data file should be existed'); 58 | console.error('make your `app_default.json` configuration file in your console'); 59 | 60 | process.exit(1); 61 | } 62 | } 63 | 64 | function moduleList() { 65 | console.info('=== check module list ...'); 66 | try { 67 | require('../config/module_list.json'); 68 | } catch (e) { 69 | console.error('module data file should be existed'); 70 | console.error('run your setup script `node core/setup module` in your console'); 71 | 72 | process.exit(1); 73 | } 74 | 75 | } 76 | 77 | function checkAll(env) { 78 | // check module installed npm and bower 79 | moduleInstalled(env); 80 | 81 | // check node version 82 | nodeVersion(); 83 | 84 | // check config files 85 | appConfig(); 86 | moduleList(); 87 | 88 | return env; 89 | } 90 | 91 | module.exports = checkAll; -------------------------------------------------------------------------------- /core/lib/socket.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function bindSession(sessionMiddleware) { 4 | winston.info('Started to bind global session to socket.io system'); 5 | 6 | return function (socket, next) { 7 | sessionMiddleware(socket.request, socket.request.res, next); 8 | }; 9 | } 10 | 11 | module.exports = { 12 | bindSession: bindSession 13 | }; -------------------------------------------------------------------------------- /core/log/log-files-here.txt: -------------------------------------------------------------------------------- 1 | # log file -------------------------------------------------------------------------------- /core/middleware.js: -------------------------------------------------------------------------------- 1 | const winston = require('winston'); 2 | 3 | const misc = require('./lib/misc'); 4 | 5 | const routeTable = misc.getRouteData(); 6 | const siteThemeType = misc.siteThemeType(); 7 | 8 | // bind common parameters 9 | function exposeLocals(req, res, next) { 10 | res.locals.site = { 11 | env: BLITITOR.env, 12 | root: BLITITOR.site.service.url_prefix, // url_prefix shouldn't end with '/' 13 | theme: BLITITOR.site.service.url_prefix + '/' +BLITITOR.site.theme, 14 | adminTheme: BLITITOR.site.service.url_prefix + '/' +BLITITOR.site.adminTheme, 15 | manageTheme: BLITITOR.site.service.url_prefix + '/' +BLITITOR.site.manageTheme, 16 | themeType: siteThemeType, 17 | title: BLITITOR.site.title, 18 | url: req.path 19 | }; 20 | 21 | res.locals.route = routeTable; 22 | 23 | winston.verbose('bind locals in core: {site, route}'); 24 | next(); 25 | } 26 | 27 | function checkDatabaseConfig(req, res, next) { 28 | if (BLITITOR.tweak.passDBCheckMiddleware || BLITITOR.config.database) { 29 | next(); 30 | } else { 31 | res.redirect('/admin' + routeTable.admin.database_setup); 32 | } 33 | } 34 | 35 | // Browser Cache Control 36 | function cacheControl(req, res, next) { 37 | if (BLITITOR.config['cacheControl']) { 38 | res.set({ 39 | 'Cache-Control': 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0', 40 | 'Pragma': 'no-cache', 41 | 'Keep-Alive': 'timeout=3, max=993', 42 | }); 43 | 44 | winston.verbose('set header with no-cache'); 45 | } 46 | 47 | next(); 48 | } 49 | 50 | function testMiddleware1(req, res, next) { 51 | console.log('Route Middleware Test Method 1'); 52 | next(); 53 | } 54 | 55 | function testMiddleware2(req, res, next) { 56 | console.log('Route Middleware Test Method 2'); 57 | next(); 58 | } 59 | 60 | module.exports = { 61 | test1: testMiddleware1, 62 | test2: testMiddleware2, 63 | exposeLocals: exposeLocals, 64 | cacheControl: cacheControl, 65 | checkDatabase: checkDatabaseConfig, 66 | }; -------------------------------------------------------------------------------- /docs/blititor_logodesign.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/docs/blititor_logodesign.ai -------------------------------------------------------------------------------- /docs/case_study.md: -------------------------------------------------------------------------------- 1 | - common use case 2 | - faq section 3 | - tutorials 4 | 5 | 6 | ## production environment 7 | 8 | ### shell environment with pm2 9 | 10 | $ NODE_ENV=production pm2 start core/index.js --name 'prod-app' -------------------------------------------------------------------------------- /docs/ci.md: -------------------------------------------------------------------------------- 1 | # Blititor Logo Guide 2 | - White ver. 3 | ![logoguide_w](https://cloud.githubusercontent.com/assets/22411481/18983269/bf9e0390-8726-11e6-8b1b-542241ce4fb8.png) 4 | 5 | - Red ver. 6 | ![logoguide](https://cloud.githubusercontent.com/assets/22411481/18983301/eb47fe92-8726-11e6-9ea6-208d640e5a62.png) 7 | 8 | # Main Logo 9 | - space trimmed, transparent background 10 | 11 | ![final2_blititorlogo_t](https://cloud.githubusercontent.com/assets/22411481/18983367/3b60e1b4-8727-11e6-9bda-e305c7077950.png) 12 | 13 | - white background 14 | 15 | ![logo_bright](https://cloud.githubusercontent.com/assets/22411481/18983438/b76f2996-8727-11e6-99d4-6c6df601f100.png) 16 | 17 | - dark background 18 | 19 | ![logo_dark](https://cloud.githubusercontent.com/assets/22411481/18983441/ba253ac2-8727-11e6-8174-e7c1d59e10ec.png) 20 | 21 | # favicon (32X32 pixel) 22 | - white square 23 | 24 | ![favicon_white](https://cloud.githubusercontent.com/assets/22411481/18984323/d386e830-872c-11e6-9e10-e94d666f5009.png) 25 | 26 | - dark square 27 | 28 | ![favicon_dark](https://cloud.githubusercontent.com/assets/22411481/18984324/d3a02bb0-872c-11e6-802a-0ab84ba28c02.png) 29 | 30 | -white rounded square 31 | 32 | ![favicon_white_r](https://cloud.githubusercontent.com/assets/22411481/18984321/d385b10e-872c-11e6-8141-f313e90df652.png) 33 | 34 | 35 | - dark rounded square 36 | 37 | ![favicon_dark_r](https://cloud.githubusercontent.com/assets/22411481/18984322/d3859f84-872c-11e6-8df8-00e9a63a9558.png) 38 | 39 | 40 | -------------------------------------------------------------------------------- /docs/develop/convention.md: -------------------------------------------------------------------------------- 1 | # Conventions 2 | 3 | ## JavaScript Coding 4 | 5 | 지금은 ES5 기반의 코드로 진행 중입니다. 6 | 부분 부분 ES2015 이후의 코드를 도입하고 있습니다만 당분간 이 형태의 코드베이스를 유지하고 7 | 메이저 버전 릴리즈를 마치고 ES6 문법을 도입하도록 하겠습니다. 8 | 9 | 10 | ## Indents 11 | 12 | __could you do me a favor?__ 13 | 14 | please use 4 space or 4 tab in *.js file. 15 | but *.html, *.css depends on each css frameworks. 16 | 17 | ## Variable or Class Convention 18 | 19 | 대부분의 자바스크립트 컨벤션을 따릅니다. 20 | 21 | - 가능하면 camelCase 를 선호합니다. 22 | - 클래스는 첫문자를 대문자로 사용합니다. 23 | - 글로벌 변수와 로컬 상수는 모두 UPPER_CASE 로 사용합니다. 24 | 25 | ### Constant in JSON 26 | 27 | JSON 포맷의 상수형 데이터 타입은 snake_case 를 사용합니다. 28 | 29 | ## File name Convention 30 | 31 | 파일명은 snake_case 를 사용합니다. 물론 소문자입니다. 32 | 33 | incorrect 34 | 35 | ``` 36 | fileName.html 37 | file-name.html 38 | ``` 39 | 40 | correct 41 | 42 | ``` 43 | file_name.html ( more preferred ) 44 | filename.html 45 | ``` 46 | 47 | ### Folder name Convention 48 | 49 | 폴더 이름의 구분은 '-' 를 사용합니다. 50 | 51 | ``` 52 | long-folder-name 53 | ``` 54 | 55 | 특정 버전을 지칭할 때도 '-' 를 사용합니다. 56 | 57 | ``` 58 | newlib-1.0.1 59 | ``` 60 | 61 | ## Branch Convention 62 | 63 | 브랜치 컨벤션이 있습니다. 64 | 65 | 그동안 혼자 작업할 때는 모든 것이 `feature/feature_name` 이었는데 이걸 조금 바꿔야 할 것 같습니다. 66 | 67 | 각 브랜치는 4 종류로 구분합니다. 68 | 69 | - core 70 | - module 71 | - theme 72 | - doc 73 | 74 | 입니다. 75 | 76 | 따라서 다음과 같이 브랜치를 분기해 사용해주세요. 77 | 78 | `core/replace-module` 79 | 80 | `module/chatting-system` 81 | 82 | `theme/niki-blog` 83 | 84 | `doc/install-guide` 85 | 86 | ## Commit subject Convention 87 | 88 | 커밋 제목의 규칙은 과거형으로 적습니다. 89 | 90 | `added new theme` 91 | 92 | `implemented awesome feature` 93 | 94 | `removed unused` 95 | 96 | `fixed memory leak` 97 | 98 | 커밋 설명의 첫 두 줄은 60~80 자 미만으로 적어주세요. 한글일 경우 40자 미만이 좋습니다. 세번째 줄 다음은 한 줄 띄우고 필요한 설명을 적습니다. 99 | 100 | ``` 101 | 근처에 있는 아무나 붙잡고 휴대폰 쥐어주면서 사진 찍어달라고 부탁해보세요. 102 | (빈줄) 103 | 99프로는 갤 노트 7 아니면 다 흔쾌히 찍어줍니다. 104 | 아, 나머지 1프로는 들고 튀죠. 105 | ``` 106 | -------------------------------------------------------------------------------- /docs/develop/menu_path_system.md: -------------------------------------------------------------------------------- 1 | ## static menu 2 | 3 | this method implemented in `module/site/lib/site.js` 4 | 5 | function bindMenuToRouter(menu, router) 6 | 7 | static page menu describe here 8 | 9 | app/[app name]/menu.js 10 | 11 | each url bind to 12 | 13 | theme/page/[menu name].html 14 | 15 | these links are not included modules route paths 16 | 17 | ## module menu 18 | 19 | each module has own paths. it bound to app menu describer in `app/[app name]/index.js` -------------------------------------------------------------------------------- /docs/develop/mysql_manage.md: -------------------------------------------------------------------------------- 1 | # Mysql(MariaDB) Manage Snippets 2 | 3 | ## Create User Database 4 | 5 | login mysql client with root account 6 | 7 | ``` 8 | $ mysql -uroot -p 9 | ``` 10 | 11 | create user and database and grant privileges 12 | 13 | ``` 14 | mysql> CREATE DATABASE `name_of_database`; 15 | mysql> use mysql; 16 | mysql> select host, user, authentication_string from user; 17 | mysql> CREATE USER 'name_of_user'@'localhost' IDENTIFIED BY 'password_for_user'; 18 | mysql> CREATE USER 'name_of_user'@'192.168.%' IDENTIFIED BY 'password_for_user'; 19 | mysql> GRANT ALL PRIVILEGES ON *.* TO 'name_of_user'@'localhost'; 20 | mysql> GRANT ALL PRIVILEGES ON *.* TO 'name_of_user'@'192.168.%'; 21 | mysql> FLUSH PRIVILEGES; 22 | ``` 23 | 24 | if your user's password didn't update then use this command 25 | 26 | ``` 27 | mysql> update user set authentication_string=password('password_for_user') where user='name_of_user'; 28 | ``` 29 | -------------------------------------------------------------------------------- /docs/develop/windows.md: -------------------------------------------------------------------------------- 1 | # WINDOWS ENVIRONMENTS 2 | 3 | ## build tools 4 | 5 | make sure native build tools. open administrator mode command line or powershell 6 | 7 | > npm -g i windows-build-tools 8 | 9 | ```powershell 10 | PS C:\Windows\system32> npm -g i windows-build-tools 11 | 12 | > windows-build-tools@5.0.0 postinstall C:\Users\soomtong\AppData\Roaming\npm\node_modules\windows-build-tools 13 | > node ./dist/index.js 14 | 15 | Downloading vs_BuildTools.exe 16 | [> ] 0.0% (0 B/s) 17 | Downloaded vs_BuildTools.exe. Saved to C:\Users\soomtong\.windows-build-tools\vs_BuildTools.exe. 18 | 19 | Starting installation... 20 | Launched installers, now waiting for them to finish. 21 | This will likely take some time - please be patient! 22 | 23 | Status from the installers: 24 | ---------- Visual Studio Build Tools ---------- 25 | Successfully installed Visual Studio Build Tools. 26 | ------------------- Python -------------------- 27 | Python 2.7.15 is already installed, not installing again. 28 | 29 | Now configuring the Visual Studio Build Tools.. 30 | 31 | All done! 32 | 33 | + windows-build-tools@5.0.0 34 | updated 1 package in 10.853s 35 | ``` 36 | 37 | and set env for python if you are not set it. 38 | 39 | ```powershell 40 | setx PYTHON "%USERPROFILE%\.windows-build-tools\python27\python.exe" 41 | ``` 42 | 43 | or update your own environments manager 44 | 45 | ## install package 46 | 47 | ``` 48 | Repository\blititor> npm config set python 'C:\Program Files\Python\python.exe' 49 | Repository\blititor> npm i 50 | ``` 51 | 52 | 53 | -------------------------------------------------------------------------------- /docs/event/2016-09-24.md: -------------------------------------------------------------------------------- 1 | # 일일보고 2 | 3 | > 블리티터 프로젝트 소개와 팀원간 아이스브레이킹과 함께 프로젝트에 대한 이야기를 나누었습니다. 4 | 5 | 멘토의 백그라운드에 대한 얘기를 하면서 Node.js 의 매력과 한계에 대한 잡담으로 블리티터 프로젝트의 필요성에 대해 설명 및 현 상황에 대한 이야기를 나누었습니다. 6 | 7 | 깃헙 팀과 코드리뷰 팀을 나누어 멘토링을 진행했습니다. 코드리뷰 팀의 경우 인스톨 관련한 이슈가 있어 의견을 나누기도 했으며 부족한 부분을 점검하고 개선하기로 했습니다. 8 | 9 | 깃헙 팀의 경우 마크다운에 대한 간략한 이야기를 나누었습니다. 10 | 11 | 마지막에는 현재 소스코드를 다운로드하여 블리티터를 구동하는 데모 시간을 갖고 간략하게 웹 서비스를 위한 각 코드의 흐름에 대해 설명했습니다. 12 | 13 | 1. 프로젝트 그룹 분할 14 | 15 | - 설치 가이드 제작: 메인 레포지토리의 `/docs/blititor_install_guide.md`, `/docs/blititor_app_module_structure.md` 16 | - 블리티터 소개 페이지 제작: 메인 레포지토리의 `gh-pages` 에 등록 (blititor.com 공식 페이지로 사용됨) 17 | - 모듈 개발: 플레인 테마 기반 등록 계정간 메시지 전송 확인 기능 18 | - KOSShack2016 홈페이지 업데이트: 깃헙의 Kosslab-kr 의 레포지토리를 돌며 리프레쉬(코스랩 메인 커밋 페이지, 각 레포지토리 메인, 각 레포지토리 commit(특정 브렌치), 각 레포지토리 issues 페이지)하는 페이지 추가 19 | - 템플릿 개발1: 매거진 테마 개발(백엔드 코드 제외) [메인 페이지](http://hani.co.kr/), [서브 메인](http://www.hani.co.kr/arti/opinion/home01.html?_fr=mt0), [섹션 리스트](http://www.hani.co.kr/arti/science/science_general/home01.html), [뷰 페이지](http://www.hani.co.kr/arti/science/science_general/762511.html) 20 | - 템플릿 개발2: 블로그 테마 개발(백엔드 코드 제외) [Responsive Template](http://btemplates.com/2016/blogger-template-rareti/demo/) ([Direct Link](http://rareti-btemplates.blogspot.kr/)) 21 | - 템플릿 개발3: 커뮤니티 테마 개발(백엔드 코드 제외) [커뮤니티 메인](http://www.bookk.co.kr/community), [섹션 리스트](http://www.bookk.co.kr/community/knowhow/board), [뷰 페이지](http://www.bookk.co.kr/community/knowhow/read?id=22) 22 | - 템플릿 개발4: furion 테마 어드민 페이지 (블로그 엔진용 관리자 템플릿) 23 | 24 | 2. 멘티별 역할 분담 25 | 26 | - 설치 가이드 제작: (주영택), 김용현, 박준영, 오승현, 한륜희, 황초롱, 최지훈 27 | - 블리티터 소개 페이지 제작: (주영택), 최지훈, 박준영 28 | - 모듈 개발: 박준영, 김용현, 정종호, 오승현, 황초롱, 이동규 29 | - 코스핵2016 업데이트: (주영택), 한륜희, 이혜진, 하은영 30 | - 템플릿 1: 황초롱, 하은영, 이혜진 31 | - 템플릿 2: 하은영, 이혜진 32 | - 템플릿 3: 하은영, 이혜진 33 | - 템플릿 4: 김용현, 김종현, 양현재 34 | 35 | ## 커뮤니케이션 채널 개설 36 | 37 | gitter.im 에 채널을 개설하여 github.com 연동으로 채팅을 시작했습니다. 38 | 39 | [Gitter.im 블리티터 로비](https://gitter.im/blititor/Lobby) 40 | 41 | ## 이슈, 커밋, 머지 활동(연습 활동 제외) 42 | 43 | @ledgku 님의 readme 업데이트 PR 44 | https://github.com/soomtong/blititor/pull/24 45 | 머지 되었습니다. 46 | https://github.com/soomtong/blititor/commit/281a9eeb8a2bbec645a1baab9bc58c6d5955ed33 47 | 48 | @ledgku 님의 이슈가 오픈되었습니다. 49 | https://github.com/soomtong/blititor/issues/23 50 | 51 | @upgle 님의 이슈 오픈되었습니다. 52 | https://github.com/soomtong/blititor/issues/22 53 | 54 | ## 참여자 명단 55 | 56 | - 이혜진 57 | - 양현재 58 | - 박준영 59 | - 김용현 60 | - 황초롱 61 | - 김종현 62 | - 하은영 63 | - 최지훈 64 | - 오승현 65 | - 정종호 66 | - 이동규 67 | - 한륜희 68 | - 주영택(멘토) 69 | 70 | -------------------------------------------------------------------------------- /docs/event/2016-09-25.md: -------------------------------------------------------------------------------- 1 | # 일일보고 2 | 3 | > 블리티터 모듈 개발팀 미팅, 테마 개발팀 미팅이 있었습니다. 그 외 온라인으로 채팅하며 이슈를 등록하고 논의하고 PR 을 보내고 Merge 하였습니다. 4 | 5 | 휴일임에도 불고하고 맨투맨 멘토링이 필요한 분을 만났습니다. 점심부터 밤까지 선릉 KOSSLAB 에서 컨트리뷰톤을 진행하였습니다. 6 | 7 | 어제 작성한 프로젝트 분담과 역할 배분에 따라 자신이 필요한 부분의 질문과 답변을 진행하였습니다. 8 | 9 | ## 활동 내용 10 | 11 | 본격적인 활동에 시작한 분도 계시고 휴일이라 쉬고 계신 분도 계십니다만 모두 어제 정리한 내용을 확인하시고 응답해 주셨으며 각자 분담된 내용에 대해 채팅 시스템을 통해 해카톤에 임하셨습니다. 12 | 13 | 오늘부터는 연습용 레포지토리가 아닌 실제 작업하고 있는 멘토의 레포지토리를 포크하여 각자 작업을 시작하였습니다. 14 | 15 | 특히, 각 플랫폼 간 해결하지 못한 디펜던시 문제를 해결하여, 윈도우즈, 매킨토시, 리눅스 시스템에서 별도의 작업 필요없이 블리티터 프로젝트를 설치해 사용하게 되었습니다. 16 | 17 | ### 요약 18 | 19 | | 오늘의 풀 리퀘스트 | 머지된 풀 리퀘스트 | 오늘 생성된 이슈 | 종결된 이슈 | 20 | | --- | --- | --- | --- | 21 | | 5건 | 5건 | 8건 | 4건 | 22 | 23 | 4명의 멤버가 30 커밋을 수행했으며 36 개의 파일을 추가/변경하였습니다. 24 | 25 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-25-1.png) 26 | 27 | ### 이슈 28 | 29 | 오늘 생성되고 해결된 이슈는 아래와 같습니다. 30 | 31 | @soomtong 32 | bind custom domain https://github.com/soomtong/blititor/issues/25 33 | 34 | @parkjunyoung 35 | Mac에서 필수모듈 bcrypt 설치 오류 문제 https://github.com/soomtong/blititor/issues/28 36 | 37 | @0122hey 38 | Windows10 에서 패키지 설치 문제 https://github.com/soomtong/blititor/issues/29 39 | 40 | @soomtong -> @ledgku 41 | CLI 셋업시 데이터베이스 설정 시점에 prefix 넣기 항목 추가하기 https://github.com/soomtong/blititor/issues/30 42 | 43 | @ho1234c 44 | 마지막에 가입한 유저는 로그인이 안됩니다. https://github.com/soomtong/blititor/issues/31 45 | 46 | @upgle 47 | [Bug] 동일 Email 로 가입시 Duplicate entry 에러와 함께 App이 죽는 문제 https://github.com/soomtong/blititor/issues/33 48 | 49 | ### 풀 리퀘스트 50 | 51 | @ledgku 52 | Modify README.md. database configurations and theme configuration https://github.com/soomtong/blititor/pull/24 53 | 54 | @ledgku 55 | Modify index.html, add database and theme configurations command https://github.com/soomtong/blititor/pull/26 56 | 57 | @ho1234c 58 | fix "admin" command at cli. https://github.com/soomtong/blititor/pull/27 59 | 60 | @upgle 61 | npm update socket.io 1.3.6 -> 1.4.8 https://github.com/soomtong/blititor/pull/32 62 | 63 | @upgle 64 | [New Feature] chatting system https://github.com/soomtong/blititor/pull/34 65 | 66 | ### 오프라인 활동 67 | 68 | 선릉 KOSSLAB 에서 행아웃 하였습니다. 69 | 70 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-25-2.png) 71 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-25-4.png) 72 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-25-3.png) 73 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-25-5.png) 74 | 75 | 76 | ## 참여자 명단 77 | 78 | - 오승현(@upgle) 79 | - 박준영(@parkjunyoung) 80 | - 황초롱(@ChorongHwang) 81 | - 하은영(@0122hey) 82 | - 이혜진(@melthleeth) 83 | - 양현재(@greenbag) 84 | - 김용현(@yonghyun123) 85 | - 김종현(@60112337) 86 | - 최지훈(@kafkalen) 87 | - 한륜희(@ryuneeee) 88 | - 정종호(@ho1234c) 89 | - 이동규(@ledgku) 90 | - 주영택(멘토) 91 | -------------------------------------------------------------------------------- /docs/event/2016-09-26.md: -------------------------------------------------------------------------------- 1 | # 일일보고 2 | 3 | > 온라인에서는 계속 이슈와 프로젝트 논의가 있었으며 코어 패치를 위해 오프라인 미팅이 한 건 있었습니다. 4 | 5 | 온라인 가이드 중 비디오 튜토리얼 작업을 진행하였습니다. 6 | 코어 패치 맨토링이 필요하여 선릉 KOSSLAB 에서 오프라인 미팅을 가졌습니다. 7 | 8 | 1. 멘티별 역할 재 분담 9 | 10 | - 설치 가이드 제작: 김용현, 박준영 11 | - 가이드 영상 제작: 최지훈 12 | - 글로벌 테스팅, 버그 패치: 김용현, 김종현, 양현재 13 | - 모듈 개발: 박준영, 김용현, 정종호, 오승현, 황초롱, 김종현 14 | - 코어 개발: 이동규, 오승현, 황초롱 15 | - 코스핵2016 업데이트: 한륜희, 이혜진 16 | - 신규 템플릿:하은영 17 | 18 | ## 활동 내용 19 | 20 | 블리티터 프로젝트 활용을 하면서 발생하는 버그가 리포트 되었고 능력에 따라 코드를 패치하고 풀 리퀘스트를 보내기 시작했습니다. 21 | 22 | 특히 비디오 튜토리얼 작업을 하여 해카톤에 참여하는 멘티 뿐 아니라 추후 블리티터를 활용하고 싶은 많은 개발자를 위해 가이드를 제공할 수 있게 되었습니다. 23 | 24 | @kafkalen 25 | 스크린 녹화 및 오디오 녹음 후 영상 편집, 유투브 업로드 작업 진행 26 | 27 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-26-4.png) 28 | 29 | 1. [블리티터 설치 전 준비 사항](https://www.youtube.com/watch?v=KAI_bsBqj0Y) 30 | 31 | > Git, Node.JS, VS Code 설치 32 | 33 | 2. [블리티터 설치 과정](https://www.youtube.com/watch?v=bnkFwKsgWeU) 34 | 35 | > Clone, Package Install, Setup, Run 36 | 37 | ### 요약 38 | 39 | | 오늘의 풀 리퀘스트 | 머지된 풀 리퀘스트 | 오늘 생성된 이슈 | 종결된 이슈 | 40 | | --- | --- | --- | --- | 41 | | 5건 | 4건 | 2건 | 0건 | 42 | 43 | 4명의 멤버가 18 커밋을 수행했으며 19 개의 파일을 추가/변경하였습니다. 44 | 45 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-26-1.png) 46 | 47 | ### 이슈 48 | 49 | 오늘 생성되고 해결된 이슈는 아래와 같습니다. 50 | 51 | @soomtong -> @ledgku 52 | 초기 셋업 옵션 중 `all` 옵션 미구현 enhancement https://github.com/soomtong/blititor/issues/28 53 | 54 | @soomtong 55 | 데이터베이스 세팅 파일 중복 문제 enhancement https://github.com/soomtong/blititor/issues/42 56 | 57 | ### 풀 리퀘스트 58 | 59 | @upgle 60 | added bower socket.io.js enhancement https://github.com/soomtong/blititor/pull/35 61 | 62 | @ho1234c 63 | Added current user list, fixed typo in name of passport.js. https://github.com/soomtong/blititor/pull/36 64 | 65 | @parkjunyoung 66 | chatting scheme setting https://github.com/soomtong/blititor/pull/37 67 | 68 | @parkjunyoung 69 | 채팅 모듈 테이블 및 index셋팅 수정 https://github.com/soomtong/blititor/pull/38 70 | 71 | @ledgku 72 | Add prompt message about prefix and configuration code enhancement https://github.com/soomtong/blititor/pull/39 73 | 74 | @ho1234c 75 | added login page to Plain theme. https://github.com/soomtong/blititor/pull/40 76 | 77 | ### 오프라인 활동 78 | 79 | 선릉 KOSSLAB 에서 행아웃 하였습니다. 80 | 81 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-26-2.png) 82 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-26-3.png) 83 | 84 | ## 참여자 명단 85 | 86 | - 오승현(@upgle) 87 | - 박준영(@parkjunyoung) 88 | - 황초롱(@ChorongHwang) 89 | - 하은영(@0122hey) 90 | - 이혜진(@melthleeth) 91 | - 양현재(@greenbag) 92 | - 김용현(@yonghyun123) 93 | - 김종현(@60112337) 94 | - 최지훈(@kafkalen) 95 | - 한륜희(@ryuneeee) 96 | - 정종호(@ho1234c) 97 | - 이동규(@ledgku) 98 | - 주영택(멘토) 99 | -------------------------------------------------------------------------------- /docs/event/2016-09-27.md: -------------------------------------------------------------------------------- 1 | # 일일보고 2 | 3 | > 온라인에서는 계속 이슈와 프로젝트 논의가 있었으며 진행 상황 공유와 팀 협업을 오프라인 미팅이 있었습니다. 4 | 5 | 어제에 이어 온라인 가이드 중 비디오 튜토리얼 작업을 진행하였습니다. 6 | 진행 상황 공유와 팀 매니징을 위해 위해 선릉 KOSSLAB 에서 오프라인 미팅을 가졌습니다. 7 | 8 | 1. 멘티별 역할 재 분담 9 | 10 | - 설치 가이드 제작: 김용현, 김종현 11 | - 가이드 영상 제작: 최지훈 12 | - 글로벌 테스팅, 버그 패치: 김용현, 김종현, 양현재 13 | - 모듈 개발: 박준영, 오승현, 황초롱, 정종호 14 | - 코어 개발: 이동규, 오승현 15 | - 코스핵2016 업데이트: 한륜희 16 | - 신규 템플릿: 하은영 17 | - 로고 디자인 및 신규 디자인: 이혜진 18 | 19 | ## 활동 내용 20 | 21 | 버그 리포트와 개선 요구를 위해 이슈를 생성하면서 패치를 진행했습니다. 어제에 이어 추가로 비디오 튜토리얼을 제작했습니다. 22 | 23 | 저녁엔 팀 매니징과 진행 상황 공유 그리고 맨투맨 가이드를 위해 오프라인 행아웃을 진행했습니다. (무려 밤 11시까지) 24 | 25 | @kafkalen 26 | 스크린 녹화 및 오디오 녹음 후 영상 편집, 유투브 업로드 작업 진행 27 | 28 | 1. [블리티터 설치 전 준비 사항](https://www.youtube.com/watch?v=KAI_bsBqj0Y) 29 | 30 | > Git, Node.JS, VS Code 설치 31 | 32 | 2. [블리티터 설치 과정](https://www.youtube.com/watch?v=bnkFwKsgWeU) 33 | 34 | > Clone, Package Install, Setup, Run 35 | 36 | 3. [블리티터 실행 & 커밋](https://www.youtube.com/watch?v=63lpJD36cnM) 37 | 38 | > Run, Edit, Commit 39 | 40 | ### 요약 41 | 42 | | 오늘의 풀 리퀘스트 | 머지된 풀 리퀘스트 | 오늘 생성된 이슈 | 종결된 이슈 | 43 | | --- | --- | --- | --- | 44 | | 2건 | 2건 | 3건 | 4건 | 45 | 46 | 5명의 멤버가 9 커밋을 수행했으며 15 개의 파일을 추가/변경하였습니다. 47 | 48 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-27-1.png) 49 | 50 | ### 이슈 51 | 52 | 오늘 생성되고 해결된 이슈는 아래와 같습니다. 53 | 54 | @soomtong -> @ryuneeee 55 | 초기 구동시 패스워드 노출 되는 부분 **** 표로 변경 https://github.com/soomtong/blititor/issues/43 56 | 57 | @soomtong 58 | Kosshack2016 테마 개선 https://github.com/soomtong/blititor/issues/44 59 | 60 | @upgle 61 | Plain theme 에서 로그인, 로그아웃 같이 출력되는 버그 https://github.com/soomtong/blititor/issues/46 62 | 63 | @melthleeth 64 | 데이터베이스가 없는 상태에서 설치하면 발생하는 오류 https://github.com/soomtong/blititor/issues/47 65 | 66 | @ledgku 67 | core/setup.js db-init이 정상적으로 작동하지 않는 문제 https://github.com/soomtong/blititor/issues/48 68 | 69 | @0122hey 70 | npm install 설치 시 fatal error:c1060 : 컴파일러 힙 공간이 부족합니다. https://github.com/soomtong/blititor/issues/50 71 | 72 | @ChorongHwang -> @soomtong 73 | 팀블로그에서 새 글 저장이 안되는 오류 https://github.com/soomtong/blititor/issues/51 74 | 75 | ### 풀 리퀘스트 76 | 77 | @upgle 78 | fixed account duplicate entry error issue #33 https://github.com/soomtong/blititor/pull/45 79 | 80 | @ChorongHwang 81 | add my name : Chorong Hwang https://github.com/soomtong/blititor/pull/49 82 | 83 | ### 오프라인 활동 84 | 85 | 선릉 KOSSLAB 에서 행아웃 하였습니다. 86 | 87 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-27-2.png) 88 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-27-4.png) 89 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-27-5.png) 90 | 91 | ## 참여자 명단 92 | 93 | - 오승현(@upgle) 94 | - 박준영(@parkjunyoung) 95 | - 황초롱(@ChorongHwang) 96 | - 하은영(@0122hey) 97 | - 이혜진(@melthleeth) 98 | - 양현재(@greenbag) 99 | - 김용현(@yonghyun123) 100 | - 김종현(@60112337) 101 | - 최지훈(@kafkalen) 102 | - 한륜희(@ryuneeee) 103 | - 정종호(@ho1234c) 104 | - 이동규(@ledgku) 105 | - 주영택(멘토) 106 | -------------------------------------------------------------------------------- /docs/event/2016-09-28.md: -------------------------------------------------------------------------------- 1 | # 일일보고 2 | 3 | > 온라인에서는 계속 이슈와 프로젝트 논의가 있었으며 개별 멘토링을 진행했습니다. 4 | 5 | 노드의 async 모듈 사용관련 한 콜백 문제를 해결해 `블리티터` 셋업 과정에 작은 진전이 있었습니다. 디자인에 관심과 재능이 있는 멘티의 새로운 로고 시안이 발표되어 모두 즐거워했습니다. 6 | 그리고, 그간 활동이 없었던 멘티의 숙제 제출 컨트리뷰션이 있었습니다. 7 | 8 | 1. 멘티별 역할 재 분담 9 | 10 | - 컨트리뷰톤 인증: 김종현, 김용현 11 | - 가이드 영상 제작: 최지훈 12 | - 글로벌 테스팅, 버그 패치: 황초롱, 양현재 13 | - 코어 패치/모듈 개발: 박준영, 정종호, 오승현, 이동규 14 | - 코스핵2016 업데이트: 한륜희 15 | - 신규 템플릿: 하은영 16 | - 로고 디자인: 이혜진 17 | 18 | ## 활동 내용 19 | 20 | 셋업 과정에 있었던 요구사항을 해결하는 큰 성과가 있었습니다. 이 부분은 제법 난이도가 있는 것이라 멘토 본인도 나중에 완성하려 했었던 기능입니다. 제법 노드에 익숙해진 멘티들이 이 문제를 해결해주었습니다. 21 | 또한 깃허브에 익숙한 멘티에게 공동작업자 권한을 부여했습니다. 22 | 그 외 버그 리포트와 개선 요구를 위해 이슈를 생성하면서 패치를 진행했습니다. 23 | 24 | 저녁엔 맨투맨 가이드를 위해 오프라인 행아웃을 진행했습니다. 25 | 26 | ### 요약 27 | 28 | | 오늘의 풀 리퀘스트 | 머지된 풀 리퀘스트 | 오늘 생성된 이슈 | 종결된 이슈 | 29 | | --- | --- | --- | --- | 30 | | 4건 | 4건 | 2건 | 6건 | 31 | 32 | 4명의 멤버가 14 커밋을 수행했으며 45 개의 파일을 추가/변경하였습니다. 33 | 34 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-28-1.png) 35 | 36 | ### 이슈 37 | 38 | 오늘 생성되고 해결된 이슈는 아래와 같습니다. 39 | 40 | @ChorongHwang 41 | [팀블로그] 가입 후에도 가입버튼이 변경되지 않음 https://github.com/soomtong/blititor/issues/52 42 | 43 | @ChorongHwang 44 | 방명록에서 reply한 것과 아닌 것의 차이가 불분명합니다. https://github.com/soomtong/blititor/issues/53 45 | 46 | ### 풀 리퀘스트 47 | 48 | @ho1234c 49 | Fixed issue #41(초기 셋업 옵션 중 `all` 옵션 미구현) https://github.com/soomtong/blititor/pull/54 50 | 51 | @ho1234c 52 | Connect database to chat module https://github.com/soomtong/blititor/pull/55 53 | 54 | ### 오프라인 활동 55 | 56 | 선릉 KOSSLAB 에서 행아웃 하였습니다. 57 | 58 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-28-2.png) 59 | 60 | ## 참여자 명단 61 | 62 | - 오승현(@upgle) 63 | - 박준영(@parkjunyoung) 64 | - 황초롱(@ChorongHwang) 65 | - 하은영(@0122hey) 66 | - 이혜진(@melthleeth) 67 | - 양현재(@greenbag) 68 | - 김용현(@yonghyun123) 69 | - 김종현(@60112337) 70 | - 최지훈(@kafkalen) 71 | - 한륜희(@ryuneeee) 72 | - 정종호(@ho1234c) 73 | - 이동규(@ledgku) 74 | - 주영택(멘토) 75 | -------------------------------------------------------------------------------- /docs/event/2016-09-29.md: -------------------------------------------------------------------------------- 1 | # 일일보고 2 | 3 | > 온라인에서는 계속 이슈와 프로젝트 논의가 있었으며 마지막 개별 멘토링을 진행했습니다. 4 | 5 | 처음 사용자를 위한 프로세스의 개선이 많았습니다. 셋업 과정을 진행하는 코드에 예외처리가 부족했는데 이에 대한 보완 작업이 이루어졌습니다. 6 | 7 | 1. 멘티별 역할 재 분담 8 | 9 | - 가이드 영상 제작: 최지훈 10 | - 글로벌 테스팅: 황초롱, 김종현, 김용현, 양현재 11 | - 코어 패치/모듈 개발: 박준영, 정종호, 오승현, 이동규 12 | - 코스핵2016 업데이트: 한륜희 13 | - 신규 템플릿: 하은영 14 | - 로고 디자인: 이혜진 15 | 16 | ## 활동 내용 17 | 18 | 등록된 로고를 투표하여 가장 많은 표를 받은 로고로 C.I 작업이 진행되었습니다. 19 | 오후엔 맨투맨 가이드를 위해 오프라인 행아웃을 진행했습니다. 20 | 채팅 모듈은 거의 완성이 되었습니다. 21 | 22 | ### 요약 23 | 24 | | 오늘의 풀 리퀘스트 | 머지된 풀 리퀘스트 | 오늘 생성된 이슈 | 종결된 이슈 | 25 | | --- | --- | --- | --- | 26 | | 8건 | 8건 | 1건 | 8건 | 27 | 28 | 6명의 멤버가 22 커밋을 수행했으며 29 개의 파일을 추가/변경하였습니다. 29 | 30 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-29-1.png) 31 | 32 | ### 이슈 33 | 34 | 오늘 생성되고 해결된 이슈는 아래와 같습니다. 35 | 36 | @upgle 37 | 로그인 안하고 채팅 페이지 접근시 앱이 죽어버리는 문제 https://github.com/soomtong/blititor/issues/69 38 | 39 | @ledgku 40 | core/setup.js admin에서 기존 존재하는 id를 입력하면 콘솔에 에러를 출력하는 문제 https://github.com/soomtong/blititor/issues/65 41 | 42 | @soomtong 43 | replace rare code with minimist in core/setup.js https://github.com/soomtong/blititor/issues/61 44 | 45 | @ho1234c 46 | 크로스브라우징이슈 https://github.com/soomtong/blititor/issues/59 47 | 48 | @ho1234c 49 | chatting module에서 disconnect event를 받지 못하는 문제 https://github.com/soomtong/blititor/issues/58 50 | 51 | @melthleeth 52 | 로고 스타일 투표 https://github.com/soomtong/blititor/issues/57 53 | 54 | @ho1234c 55 | chatting module에서 guest로 입장시 user list에 뜨지 않는 문제 https://github.com/soomtong/blititor/issues/56 56 | 57 | ### 풀 리퀘스트 58 | 59 | @ChorongHwang 60 | 이슈 #52 수정 https://github.com/soomtong/blititor/pull/71 61 | 62 | @upgle 63 | Fixed issue #69 https://github.com/soomtong/blititor/pull/70 64 | 65 | @ho1234c 66 | Added chatting module to simplestrap theme. https://github.com/soomtong/blititor/pull/68 67 | 68 | @ChorongHwang 69 | replaced name https://github.com/soomtong/blititor/pull/67 70 | 71 | @ledgku 72 | Fixed #65(core/setup.js admin에서 기존 존재하는 id를 입력하면 콘솔에 에러를 출력하는 문제) https://github.com/soomtong/blititor/pull/66 73 | 74 | @ho1234c 75 | Added error page to plane theme. https://github.com/soomtong/blititor/pull/64 76 | 77 | @ledgku 78 | Fixed #23 Module mysql-connection-manager is deprecated https://github.com/soomtong/blititor/pull/63 79 | 80 | @melthleeth 81 | 로고 업로드 및 저번에 테스트용으로 올린 psd 파일 삭제 https://github.com/soomtong/blititor/pull/62 82 | 83 | @ho1234c 84 | Fixed issue #56, #58 https://github.com/soomtong/blititor/pull/60 85 | 86 | ### 오프라인 활동 87 | 88 | 선릉 KOSSLAB 에서 행아웃 하였습니다. 89 | 90 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-29-2.jpg) 91 | 92 | ## 참여자 명단 93 | 94 | - 오승현(@upgle) 95 | - 박준영(@parkjunyoung) 96 | - 황초롱(@ChorongHwang) 97 | - 하은영(@0122hey) 98 | - 이혜진(@melthleeth) 99 | - 양현재(@greenbag) 100 | - 김용현(@yonghyun123) 101 | - 김종현(@60112337) 102 | - 최지훈(@kafkalen) 103 | - 한륜희(@ryuneeee) 104 | - 정종호(@ho1234c) 105 | - 이동규(@ledgku) 106 | - 주영택(멘토) 107 | -------------------------------------------------------------------------------- /docs/event/2016-09-30.md: -------------------------------------------------------------------------------- 1 | # 일일보고 2 | 3 | > 마지막 피치를 올렸습니다. 일주일간의 장정을 마칩니다. 4 | 5 | C.I 가 완성되었고 채팅 모듈은 완성에 가까워졌습니다. 저마다의 수준에 맞는 역할을 감당하였고 취지에 합당한 경험을 가졌습니다. 6 | 7 | - 가이드 영상 제작: 최지훈 8 | - 글로벌 테스팅: 황초롱, 김종현, 김용현, 양현재 9 | - 코어 패치/모듈 개발: 박준영, 정종호, 오승현, 이동규 10 | - 코스핵2016 업데이트: 한륜희 11 | - 신규 템플릿: 하은영 12 | - 로고 디자인: 이혜진 13 | 14 | ## 활동 내용 15 | 16 | 채팅 모듈 개발을 마무리하였습니다. 내일 있을 프리젠테이션을 위해 자료 정리를 하였고 파일을 만들었습니다. 17 | 멘토의 개인적 사정으로 오프라인 모임은 진행하지 않았습니다. 18 | 19 | ### 요약 20 | 21 | | 오늘의 풀 리퀘스트 | 머지된 풀 리퀘스트 | 오늘 생성된 이슈 | 종결된 이슈 | 22 | | --- | --- | --- | --- | 23 | | 10건 | 10건 | 6건 | 6건 | 24 | 25 | 9명의 멤버가 19 커밋을 수행했으며 26 개의 파일을 추가/변경하였습니다. 26 | 27 | ![](https://dl.dropboxusercontent.com/u/53671575/kosshack2016-team8-2016-09-30-1.png) 28 | 29 | ### 이슈 30 | 31 | 오늘 생성되고 해결된 이슈는 아래와 같습니다. 32 | 33 | @soomtong -> @ho1234c 34 | 윈도우즈 환경에서 setup theme 작업시 md 파일 정보 출력 문제 https://github.com/soomtong/blititor/issues/79 35 | 36 | @ledgku 37 | 로그인시 패스워드 hash값이 콘솔에 출력되는 문제 https://github.com/soomtong/blititor/issues/79 38 | 39 | @ho1234c -> @ho1234c 40 | team blog module에서 tag를 클릭하면 페이지를 찾지 못합니다. https://github.com/soomtong/blititor/issues/76 41 | 42 | @ledgku 43 | 로그인시 b_user 테이블의 login_counter, last_logged_at이 업데이트 되지 않는 문제 https://github.com/soomtong/blititor/issues/74 44 | 45 | ### 풀 리퀘스트 46 | 47 | @melthleeth 48 | upload ci page illustrator file https://github.com/soomtong/blititor/pull/84 49 | 50 | @ho1234c 51 | Fixed #80(윈도우즈 환경에서 setup theme 작업시 md 파일 정보 출력 문제) https://github.com/soomtong/blititor/pull/83 52 | 53 | @upgle 54 | Fixed Chatting 모듈에서 나에게 귓속말을 보내는 문제 https://github.com/soomtong/blititor/pull/82 55 | 56 | @parkjunyoung 57 | 귓속말하기 구현 https://github.com/soomtong/blititor/pull/81 58 | 59 | @melthleeth 60 | add ci.md and delete sample directory https://github.com/soomtong/blititor/pull/78 61 | 62 | @ho1234c 63 | Added insert tag code to insertPost methed in teamblog module. https://github.com/soomtong/blititor/pull/77 64 | 65 | @ledgku 66 | Fixed #74(로그인시 b_user 테이블의 login_counter, last_logged_at이 업데이트 되지 않는 문제) https://github.com/soomtong/blititor/pull/75 67 | 68 | @ChorongHwang 69 | replaced member names https://github.com/soomtong/blititor/pull/73 70 | 71 | @songru 72 | name replaced https://github.com/soomtong/blititor/pull/72 73 | 74 | ### 최종 완성된 C.I 75 | 76 | 화이트 버전 77 | 78 | ![](https://cloud.githubusercontent.com/assets/22411481/18983269/bf9e0390-8726-11e6-8b1b-542241ce4fb8.png) 79 | 80 | 레드 버전 81 | 82 | ![](https://cloud.githubusercontent.com/assets/22411481/18983301/eb47fe92-8726-11e6-9ea6-208d640e5a62.png) 83 | 84 | ## 참여자 명단 85 | 86 | - 오승현(@upgle) 87 | - 박준영(@parkjunyoung) 88 | - 황초롱(@ChorongHwang) 89 | - 하은영(@0122hey) 90 | - 이혜진(@melthleeth) 91 | - 양현재(@greenbag) 92 | - 김용현(@yonghyun123) 93 | - 김종현(@60112337) 94 | - 최지훈(@kafkalen) 95 | - 한륜희(@ryuneeee) 96 | - 정종호(@ho1234c) 97 | - 이동규(@ledgku) 98 | - 주영택(멘토) 99 | -------------------------------------------------------------------------------- /docs/event/kosshack2016.md: -------------------------------------------------------------------------------- 1 | # KossLab Hackathon (Contributhon) 2016 2 | 3 | > open source contribution competition with mentoring in a week 4 | 5 | **2016 KOSS Hackathon (2016 공개SW 해카톤)** 6 | 7 | 오픈소스 누구나 할 수 있다! 8 | 2016 공개SW 해카톤! (2016 KOSS Hackathon) 9 | 공개SW 고급개발자인 멘토와 함께 1주일간 공개SW 프로젝트 기여활동에 직접 참여하는 경험을 해보는 행사입니다. 10 | 말로만 듣던 오픈소스! 이제 직접 참여해보세요! 11 | 12 | ## Public Information 13 | 14 | - Web Site: kosshackathon.kr 15 | - Github Organization: github.com/kosslab-kr 16 | - Github Repository: github.com/kosslab-kr/kosshack2016 17 | - Public Github Page: kosslab-kr.github.io/kosshack2016 18 | 19 | ### 행사 목적 20 | 21 | * 국내 공개SW에 대한 사회적 인식 확산 22 | * 공개SW의 개발동기 제고 및 활용 확산 23 | 24 | ### 행사 일정 25 | 26 | * 2016년 9월 24일(토) 14:00 ~ 10월 1일(토) 16:20 27 | 28 | ### 참가대상 29 | 30 | * SW개발과 공개SW에 관심이 있는 대학(원)생, 일반인 누구나 31 | * 공개SW 프로젝트에 직접 참여할 기회를 갖고 싶은 개발자 32 | 33 | ### 장소 34 | 35 | * D-Camp(9/24) 36 | * KossLab(10/1) 37 | 38 | ### 주최 & 주관 39 | 40 | * 미래창조과학부 & 정보통신산업진흥원 41 | * 한국IT비즈니스진흥협회 42 | * 공개SW개발자Lab 43 | 44 | ## Blititor Project Team 8 45 | 46 | 프로젝트 블리티터 (멘토 주영택) 47 | 48 | ### Members 49 | 50 | - replace this to your name(@upgle) 51 | - 박준영(@parkjunyoung) 52 | - 이혜진(@melthleeth) 53 | - 황초롱(@ChorongHwang) 54 | - 하은영(@0122hey) 55 | - replace this to your name(@greenbag) 56 | - replace this to your name(@yonghyun123) 57 | - 김종현(@60112337) 58 | - replace this to your name(@kafkalen) 59 | - replace this to your name(@ryuneeee) 60 | - 정종호(@ho1234c) 61 | - 이동규(@ledgku) 62 | - your name(@your id) 63 | -------------------------------------------------------------------------------- /docs/history.md: -------------------------------------------------------------------------------- 1 | # Release History 2 | 3 | ## Go Forum 4 | 5 | > 0.8.0 6 | 7 | 'Discourse' 스타일의 포럼 8 | 9 | ## BBS 10 | 11 | > 0.8.0 12 | 13 | 멀티 보드 게시판 모듈이 추가 되었습니다. 14 | 15 | ## A Team 16 | 17 | > 0.6.0 18 | 19 | 두 세가지 테마를 포함한 바로 사용 가능한 팀블로그 모듈을 릴리즈 합니다. 20 | 21 | ## Restructuring 22 | 23 | > 0.5.0 24 | 25 | 코어 구조 개선 및 싱글 보드 게시판 26 | 27 | ## Smart Network Platform Test 28 | 29 | > 0.4.0 30 | 31 | 앱 스토어 기능을 실험합니다. 여기엔 서버에 설치된 네이티브 애플리케이션과 상호 통신하는 기능을 포함하고 있습니다. 32 | 33 | ## Exhibition 2 34 | 35 | > 0.3.0 36 | 37 | KOSSCon 2016 테마를 릴리즈합니다. 38 | 39 | - Reservation 모듈이 포함되었습니다. 40 | - Gallery 모듈이 포함되었습니다. 41 | - 각 앱의 스캐폴딩이 개선되었습니다. 42 | 43 | ## Exhibition 44 | 45 | > 0.2.0 46 | 47 | KOSSHack 2016 테마를 릴리즈합니다. 컨트리뷰톤 동안 다양한 이슈가 생성/해결되었고 컨트리뷰터가 추가되었습니다. 48 | 49 | - Guestbook 모듈이 포함되었습니다. 50 | - Chatting 모듈이 포함되었습니다. 51 | - 설정 파일 관련 코드 개선 52 | 53 | --- 54 | 55 | ## First Step 56 | 57 | > 0.1.0 58 | 59 | 플레인 테마를 기준으로 프레임워크의 기본 구조를 완성하였습니다. 60 | 61 | - Plain 테마(관리자/운영자 테마 포함) 공개 62 | - Site.page: 특정 URL 과 테마 페이지가 연결됩니다. 63 | - 카운터 기능이 추가되었습니다. 64 | -------------------------------------------------------------------------------- /docs/install.md: -------------------------------------------------------------------------------- 1 | install guide 2 | 3 | and troubleshooting -------------------------------------------------------------------------------- /docs/tutorial/asciinema_guide_for_cli.md: -------------------------------------------------------------------------------- 1 | asciinema guide for cli.md -------------------------------------------------------------------------------- /docs/tutorial/video_guide_for_windows_10.md: -------------------------------------------------------------------------------- 1 | video guide for windows 10.md -------------------------------------------------------------------------------- /module/account/description.md: -------------------------------------------------------------------------------- 1 | ## Account 2 | 3 | > Global Account Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/account/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/account'); 2 | const { site } = require('./route'); 3 | const middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.site = site; 7 | module.exports.middleware = middleware; -------------------------------------------------------------------------------- /module/account/lib/dummy.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "email": "noname@mail.net", 4 | "password": "$2a$08$rCi5ZgC2hxQ2XE6FsV/NKebzclpyMfoAGXpW9sdBwWnqe8.DCrEty", 5 | "nickname": "무명씨" 6 | }, 7 | { 8 | "email": "test@mail.net", 9 | "password": "$2a$08$rCi5ZgC2hxQ2XE6FsV/NKebzclpyMfoAGXpW9sdBwWnqe8.DCrEty", 10 | "nickname": "테스터" 11 | } 12 | ] -------------------------------------------------------------------------------- /module/account/lib/middleware.js: -------------------------------------------------------------------------------- 1 | const winston = require('winston'); 2 | 3 | const misc = require('../../../core/lib/misc'); 4 | 5 | const userPrivilege = misc.getUserPrivilege(); 6 | const routeTable = misc.getRouteData(); 7 | 8 | function ensureAuthenticated(req, res, next) { 9 | if (req.isAuthenticated()) { 10 | return next(); 11 | } 12 | 13 | res.redirect(BLITITOR.site.service.url_prefix + '/account' + routeTable.account.signIn); 14 | } 15 | 16 | function ensureClearSession(req, res, next) { 17 | if (!req.isAuthenticated()) { 18 | return next(); 19 | } 20 | 21 | res.redirect(BLITITOR.site.service.url_prefix + '/account' + routeTable.account.info); 22 | } 23 | 24 | function ensureAdminAuthenticated(req, res, next) { 25 | if (req.isAuthenticated() && req.user.grant.includes(userPrivilege.siteAdmin)) { 26 | return next(); 27 | } 28 | 29 | res.redirect(BLITITOR.site.service.url_prefix + '/admin' + routeTable.admin.login); 30 | } 31 | 32 | function ensureManagerAuthenticated(req, res, next) { 33 | if (req.isAuthenticated() && req.user.grant.includes(userPrivilege.siteManager)) { 34 | return next(); 35 | } 36 | 37 | res.redirect(BLITITOR.site.service.url_prefix + '/manage' + routeTable.manage.login); 38 | } 39 | 40 | function exposeLocals(req, res, next) { 41 | res.locals.user = req.user; 42 | 43 | winston.verbose('bind locals in account: {user}'); 44 | next(); 45 | } 46 | 47 | module.exports = { 48 | checkSignedIn: ensureAuthenticated, 49 | checkLoggedSession: ensureClearSession, 50 | checkAdministrator: ensureAdminAuthenticated, 51 | checkManager: ensureManagerAuthenticated, 52 | exposeLocals: exposeLocals 53 | }; -------------------------------------------------------------------------------- /module/account/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "selectByID": "SELECT ?? FROM ?? WHERE `id` = ?", 3 | "selectByUUID": "SELECT ?? FROM ?? WHERE `uuid` = ?", 4 | "selectByUUIDWithAuth": "SELECT `auth`.??, `user`.?? FROM ?? as `auth`, ?? as `user` WHERE `user`.`uuid` = ? AND `auth`.`id` = `user`.`auth_id`", 5 | "selectByUserID": "SELECT ?? FROM ?? WHERE `user_id` = ?", 6 | "selectByAuthID": "SELECT ?? FROM ?? WHERE `auth_id` = ?", 7 | "selectByAuthIDWithAuth": "SELECT `auth`.??, `user`.?? FROM ?? as `auth`, ?? as `user` WHERE `user`.`auth_id` = ? AND `auth`.`id` = `user`.`auth_id`", 8 | "insertInto": "INSERT INTO ?? SET ?", 9 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 10 | "updateAccountByUUID": "UPDATE ?? SET ? WHERE `uuid` = ?" 11 | } -------------------------------------------------------------------------------- /module/account/route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const winston = require('winston'); 3 | 4 | const Passport = require('passport'); 5 | const LocalStrategy = require('passport-local').Strategy; 6 | 7 | const misc = require('../../core/lib/misc'); 8 | 9 | const account = require('./lib/account'); 10 | const middleware = require('./lib/middleware'); 11 | const passport = require('./lib/passport'); 12 | 13 | const routeTable = misc.getRouteData(); 14 | const site = express.Router(); 15 | 16 | // Passport Stuffs 17 | const passportLocalOptions = { 18 | failureRedirect: '/account' + routeTable.account.signIn, 19 | badRequestMessage: '아이디 또는 비밀번호를 입력해주세요!', 20 | failureFlash: true, 21 | }; 22 | 23 | Passport.use(new LocalStrategy({ usernameField: 'account_id', passwordField: 'account_password' }, passport.authenticate)); 24 | Passport.serializeUser(passport.serialize); 25 | Passport.deserializeUser(passport.deserialize); 26 | 27 | // router.use(middleware.exposeLocals); it used in app level not route level 28 | 29 | site.get('/', account.signIn); 30 | site.get(routeTable.account.signIn, account.signIn); 31 | site.get(routeTable.account.signUp, middleware.checkLoggedSession, account.signUp); 32 | site.get(routeTable.account.signOut, account.signOut); 33 | site.post(routeTable.account.checkToken, account.checkToken); 34 | 35 | site.post(routeTable.account.login, Passport.authenticate('local', passportLocalOptions), passport.loginSuccess, passport.loginDone); 36 | site.post(routeTable.account.register, account.register); 37 | 38 | site.get(routeTable.account.info, middleware.checkSignedIn, account.infoForm); 39 | site.post(routeTable.account.updateInfo, middleware.checkSignedIn, account.updateInfo); 40 | 41 | module.exports = { site }; -------------------------------------------------------------------------------- /module/account/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "account": { 3 | "root": "/account", 4 | "signIn": "/sign-in", 5 | "signUp": "/sign-up", 6 | "signOut": "/sign-out", 7 | "checkToken": "/check-token", 8 | "login": "/login", 9 | "register": "/register", 10 | "registerSimple": "/register-simple", 11 | "add": "/add", 12 | "info": "/info", 13 | "updateInfo": "/update" 14 | } 15 | } -------------------------------------------------------------------------------- /module/administrator/description.md: -------------------------------------------------------------------------------- 1 | ## Administrator 2 | 3 | > Global Administrator Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/administrator/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/administrator'); 2 | const { site, admin } = require('./route'); 3 | const middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.site = site; 7 | module.exports.admin = admin; 8 | module.exports.middleware = middleware; -------------------------------------------------------------------------------- /module/administrator/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | var util = require('util'); 3 | 4 | function exposeLocals(req, res, next) { 5 | winston.verbose('bind locals in administrator: {}'); 6 | next(); 7 | } 8 | 9 | module.exports = { 10 | exposeLocals: exposeLocals 11 | }; -------------------------------------------------------------------------------- /module/administrator/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "selectAccountByUUID": "SELECT ?? FROM ?? auth, ?? user WHERE auth.id = user.auth_id AND user.uuid = ?", 3 | "countAllAccount": "SELECT count(auth.id) as `count` FROM ?? auth, ?? user WHERE auth.id = user.auth_id", 4 | "readAccountByPage": "SELECT ?? FROM ?? auth, ?? user WHERE auth.id = user.auth_id ORDER BY auth.id DESC LIMIT ?, ?", 5 | "selectByUUID": "SELECT ?? FROM ?? WHERE `uuid` = ?", 6 | "selectByUUIDWithLimit": "SELECT ?? FROM ?? WHERE `uuid` = ? ORDER BY id DESC LIMIT ?", 7 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 8 | "updateAccountByUUID": "UPDATE ?? SET ? WHERE `uuid` = ?" 9 | } -------------------------------------------------------------------------------- /module/administrator/route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const winston = require('winston'); 3 | 4 | const misc = require('../../core/lib/misc'); 5 | 6 | const administrator = require('./lib/administrator'); 7 | const middleware = require('./lib/middleware'); 8 | 9 | const Account = require('../account'); 10 | 11 | const routeTable = misc.getRouteData(); 12 | const site = express.Router(); 13 | 14 | site.use(Account.middleware.exposeLocals); 15 | 16 | site.get(routeTable.admin['login'], administrator.loginForm); 17 | site.post(routeTable.admin['login'], administrator.loginProcess); 18 | 19 | // caution. use each middleware for other module's router. it affects all router exist behind 20 | const admin = express.Router(); 21 | 22 | admin.get(routeTable.admin['home'], Account.middleware.checkAdministrator, administrator.accountList); 23 | admin.get(routeTable.admin['account'], Account.middleware.checkAdministrator, administrator.accountList); 24 | admin.get(routeTable.admin['account_new'], Account.middleware.checkAdministrator, administrator.accountView); 25 | admin.post(routeTable.admin['account_add'], Account.middleware.checkAdministrator, Account.registerSimple); 26 | 27 | admin.get(routeTable.admin['account'] + '/:uuid', Account.middleware.checkAdministrator, administrator.accountView); 28 | admin.get(routeTable.admin['account_edit'] + '/:uuid', Account.middleware.checkAdministrator, administrator.accountForm); 29 | admin.post(routeTable.admin['account_edit'] + '/:uuid', Account.middleware.checkAdministrator, administrator.accountProcess); 30 | 31 | module.exports = { site, admin }; -------------------------------------------------------------------------------- /module/administrator/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "admin": { 3 | "root": "/admin", 4 | "home": "/", 5 | "login": "/login", 6 | "install": "/install", 7 | "database_setup": "/make-db-config", 8 | "database_init": "/make-db-init", 9 | "theme_setup": "/theme-config", 10 | "account": "/account", 11 | "account_edit": "/account/edit", 12 | "account_new": "/account/register", 13 | "account_add": "/account/add", 14 | "counter": "/counter" 15 | } 16 | } -------------------------------------------------------------------------------- /module/app_store/description.md: -------------------------------------------------------------------------------- 1 | ## AppStore 2 | 3 | > Simple AppStore Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/app_store/index.js: -------------------------------------------------------------------------------- 1 | var lib = require('./lib/appstore'); 2 | var route = require('./route'); 3 | var middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.route = route; 7 | module.exports.middleware = middleware; 8 | -------------------------------------------------------------------------------- /module/app_store/lib/dummy1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "IPSec 테이블 매니저", 4 | "description": "하이 퍼포먼스 로드밸런서 64비트 전용", 5 | "price": "500,000", 6 | "flag": "N", 7 | "content": "마크다운 문서", 8 | "category": 2, 9 | "image": "http://placeimg.com/320/240/tech/1", 10 | "tags": "pfkey, ipsec" 11 | }, 12 | { 13 | "title": "로드밸런서", 14 | "description": "하이 퍼포먼스 로드밸런서 64비트 전용", 15 | "price": "120,000", 16 | "content": "마크다운 문서", 17 | "category": 1, 18 | "image": "http://farm8.staticflickr.com/7448/8915936174_8d54ec76c6.jpg", 19 | "tags": "packetNgin, 로드밸런서" 20 | }, 21 | { 22 | "title": "역적 네트워크 에뮬레이터", 23 | "description": "하이 퍼포먼스 로드밸런서 64비트 전용", 24 | "price": "320,000", 25 | "category": 3, 26 | "content": "마크다운 문서", 27 | "image": "http://placeimg.com/320/240/tech/2", 28 | "tags": "구름네트웍스, 홍길동, 넷에뮬" 29 | }, 30 | { 31 | "title": "트래픽 모니터", 32 | "description": "하이 퍼포먼스 로드밸런서 64비트 전용", 33 | "price": "230,000", 34 | "content": "마크다운 문서", 35 | "category": 1, 36 | "pinned": true, 37 | "flag": "N", 38 | "image": "http://placeimg.com/320/240/tech/3", 39 | "tags": "트래픽, 홍길동, 모니터" 40 | }, 41 | { 42 | "title": "패킷컨버터", 43 | "description": "하이 퍼포먼스 로드밸런서 64비트 전용", 44 | "price": "100,000", 45 | "content": "마크다운문서", 46 | "pinned": true, 47 | "category": 4, 48 | "image": "http://placeimg.com/320/240/tech/4", 49 | "tags": "컨버터" 50 | }, 51 | { 52 | "title": "ARP Shooter", 53 | "description": "하이 퍼포먼스 로드밸런서 64비트 전용", 54 | "price": "120,000", 55 | "content": "마크다운 문서", 56 | "pinned": true, 57 | "category": 5, 58 | "image": "http://placeimg.com/320/240/tech/5", 59 | "tags": "ARP" 60 | }, 61 | { 62 | "title": "패킷보여", 63 | "description": "하이 퍼포먼스 로드밸런서 64비트 전용", 64 | "price": "120,000", 65 | "content": "패킷 다보임", 66 | "pinned": true, 67 | "image": "http://placeimg.com/320/240/tech/6", 68 | "category": 6, 69 | "tags": "DPI" 70 | }, 71 | { 72 | "title": "넷 애뮬", 73 | "description": "하이 퍼포먼스 로드밸런서 64비트 전용", 74 | "price": "1,000,000", 75 | "content": "마크다운문서", 76 | "category": 4, 77 | "image": "http://placeimg.com/320/240/tech/7", 78 | "tags": "넷애뮬" 79 | } 80 | ] 81 | -------------------------------------------------------------------------------- /module/app_store/lib/dummy2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "monitor", 4 | "title": "모니터링", 5 | "subject": "네트워크 모니터, 퍼포먼스 모니터" 6 | }, 7 | { 8 | "id": "balance", 9 | "title": "로드밸런싱", 10 | "subject": "트래픽 분산, 리버스 프록시" 11 | }, 12 | { 13 | "id": "security", 14 | "title": "시큐리티", 15 | "subject": "IPSec, 파이어월" 16 | }, 17 | { 18 | "id": "switch", 19 | "title": "스위치", 20 | "subject": "허브, 브릿지, 릴레이" 21 | }, 22 | { 23 | "id": "library", 24 | "title": "라이브러리", 25 | "subject": "패킷엔진, 리눅스 라이브러리" 26 | }, 27 | { 28 | "id": "driver", 29 | "title": "드라이버", 30 | "subject": "디바이스 드라이버" 31 | } 32 | ] 33 | -------------------------------------------------------------------------------- /module/app_store/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in appstore: {}'); 5 | next(); 6 | } 7 | 8 | module.exports = { 9 | exposeLocals: exposeLocals 10 | }; -------------------------------------------------------------------------------- /module/app_store/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "selectAll": "SELECT ?? FROM ??", 3 | "selectAllTags": "SELECT `tags` FROM ?? ORDER BY `tags` ASC", 4 | "selectAppByID": "SELECT A.*, (SELECT `category_title` FROM ?? WHERE `id` = A.`category_id`) AS `category_title`, (SELECT `category_id` FROM ?? WHERE `id` = A.`category_id`) AS `category_name` FROM ?? AS A WHERE `id` = ? LIMIT 1", 5 | "selectAppByURL": "SELECT A.*, (SELECT `category_title` FROM ?? WHERE `id` = A.`category_id`) AS `category_title`, (SELECT `category_id` FROM ?? WHERE `id` = A.`category_id`) AS `category_name` FROM ?? AS A WHERE `package_id` = ? LIMIT 1 ", 6 | "selectByUUID": "SELECT ?? FROM ?? WHERE `user_uuid` = ?", 7 | "selectByUserID": "SELECT ?? FROM ?? WHERE `user_id` = ?", 8 | "selectByCategoryID": "SELECT ?? FROM ?? WHERE `category_id` = ?", 9 | "countAll": "SELECT count(id) as `count` FROM ??", 10 | "countAllByCategory": "SELECT count(A.`id`) as `count` FROM ?? as A, ?? as B WHERE B.`category_id` = ? and A.`category_id` = B.`id`", 11 | "readStoreAppList": "SELECT A.*, (SELECT `category_title` FROM ?? WHERE `id` = A.`category_id`) AS `category_title` FROM ?? AS A ORDER BY `id` DESC LIMIT ?, ?", 12 | "readStoreAppMonthlyAll": "SELECT ?? FROM ?? WHERE YEAR(??) = ? AND MONTH(??) = ? ORDER BY `id` DESC", 13 | "readAppRecently": "SELECT ??, (SELECT `category_title` FROM ?? WHERE `id` = A.`category_id`) AS `category_title` FROM ?? AS A ORDER BY `id` DESC LIMIT ?", 14 | "readAppListByCategory": "SELECT A.*, B.`category_title` AS `category_title` FROM ?? AS A, ?? AS B WHERE B.`category_id` = ? and B.`id` = A.`category_id` ORDER BY A.`id` DESC LIMIT ?, ?", 15 | "readAppPinned": "SELECT ?? FROM ?? WHERE `pinned` = ? ORDER BY `id` DESC LIMIT ?", 16 | "selectCategoryByApp": "select ??, ?? from ?? as a, ?? as b, ?? as c where a.`id` = ? and a.`id` = b.`store_category_related_app_id` and b.`store_app_id` = c.`id`", 17 | "updateCounterByCategory": "UPDATE ?? SET ?? = ?? + 1 WHERE `tag` = ?", 18 | "selectByCategory": "SELECT `id`, `tag` FROM ?? WHERE `tag` = ? FOR UPDATE", 19 | "insertInto": "INSERT INTO ?? SET ?", 20 | "insertCategoryInto": "INSERT INTO ?? SET ? ON DUPLICATE KEY UPDATE ?", 21 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 22 | "selectOrderedAppByUser": "SELECT A.*, B.id as `ordered_id`, B.`created_at` as `purchased_at`, B.`installed_at`, B.`canceled_at` FROM ?? A, ?? B WHERE B.`user_uuid` = ? and A.`id` = B.`store_app_id` ORDER BY B.`id` DESC", 23 | "selectOrderByIDWithUUID": "SELECT * FROM ?? WHERE `store_app_id` = ? and `user_uuid` = ? ORDER BY `id` DESC", 24 | "anyAuthor": "SELECT ?? FROM ?? ORDER BY `id` ASC LIMIT 1" 25 | } -------------------------------------------------------------------------------- /module/app_store/route.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var winston = require('winston'); 3 | 4 | var misc = require('../../core/lib/misc'); 5 | 6 | var site = require('../site'); 7 | 8 | var appstore = require('./lib/appstore'); 9 | var middleware = require('./lib/middleware'); 10 | 11 | var AccountMiddleware = require('../account/lib/middleware'); 12 | 13 | var router = express.Router(); 14 | var routeTable = misc.getRouteData(); 15 | 16 | router.use(middleware.exposeLocals); 17 | 18 | // bind module router 19 | router.get(routeTable.account.login, site.redirect('/account' + routeTable.account.signIn)); 20 | 21 | router.all(routeTable.root, site.redirect(routeTable.appstore_root)); 22 | router.get(routeTable.appstore_root, appstore.index); 23 | 24 | router.get(routeTable.appstore_root + routeTable.appstore_app + '/:appNumber([0-9]+)', appstore.view); 25 | router.get(routeTable.appstore_root + routeTable.appstore_app + '/:packageName', appstore.view); 26 | 27 | router.post(routeTable.appstore_root + routeTable.appstore_app + '/:appNumber([0-9]+)/order', AccountMiddleware.checkSignedIn, appstore.order); 28 | 29 | router.get(routeTable.appstore_root + routeTable.appstore.upload, AccountMiddleware.checkSignedIn, appstore.upload); // in order to avoid conflict with `:page` params 30 | router.post(routeTable.appstore_root + routeTable.appstore.upload, AccountMiddleware.checkSignedIn, appstore.save); 31 | 32 | router.get('/account' + routeTable.appstore.list, AccountMiddleware.checkSignedIn, appstore.purchasedAppList); 33 | 34 | router.get(routeTable.appstore_root + routeTable.appstore.list, appstore.list); 35 | router.get(routeTable.appstore_root + routeTable.appstore.list + '/:page([0-9]+)', site.redirect(routeTable.appstore_root + routeTable.appstore.list)); 36 | router.get(routeTable.appstore_root + routeTable.appstore.category + '/:category' , appstore.listByCategory); 37 | 38 | module.exports = router; 39 | -------------------------------------------------------------------------------- /module/app_store/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "appstore": { 3 | "root": "/store", 4 | "list": "/apps", 5 | "category": "/category", 6 | "upload": "/upload/app" 7 | }, 8 | "appstore_app": "/app" 9 | } -------------------------------------------------------------------------------- /module/chatting/description.md: -------------------------------------------------------------------------------- 1 | ## Simple Chatting 2 | 3 | > Global Simple Chatting Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - ho1234c (github.com/ho1234c) 14 | - upgle (github.com/upgle) 15 | - parkjunyoung (github.com/parkjunyoung) 16 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/chatting/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/chatting'); 2 | const route = require('./route'); 3 | const middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.route = route; 7 | module.exports.middleware = middleware; 8 | -------------------------------------------------------------------------------- /module/chatting/lib/database.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var async = require('neo-async'); 3 | 4 | var mysql = require('mysql'); 5 | var winston = require('winston'); 6 | 7 | var common = require('../../../core/lib/common'); 8 | var misc = require('../../../core/lib/misc'); 9 | var databaseDefault = misc.getDatabaseDefault(); 10 | 11 | var tables = { 12 | chattingLog : databaseDefault.tablePrefix + 'chatting_log', 13 | user: databaseDefault.tablePrefix + 'user' 14 | }; 15 | 16 | var query = require('./query'); 17 | 18 | function deleteScheme(databaseConfiguration, callback) { 19 | var connection = mysql.createConnection({ 20 | host: databaseConfiguration.dbHost, 21 | port: databaseConfiguration.dbPort || databaseDefault.port, 22 | database: databaseConfiguration.dbName || databaseDefault.database, 23 | user: databaseConfiguration.dbUserID, 24 | password: databaseConfiguration.dbUserPassword 25 | }); 26 | 27 | var sql = "DROP TABLE IF EXISTS ??"; 28 | var tableList = [tables.chattingLog]; 29 | 30 | connection.query(sql, tableList, function (error, results, fields) { 31 | connection.destroy(); 32 | 33 | callback(databaseConfiguration); 34 | }); 35 | } 36 | 37 | function createScheme(databaseConfiguration, callback, done) { 38 | var connection = mysql.createConnection({ 39 | host: databaseConfiguration.dbHost, 40 | port: databaseConfiguration.dbPort || databaseDefault.port, 41 | database: databaseConfiguration.dbName || databaseDefault.database, 42 | user: databaseConfiguration.dbUserID, 43 | password: databaseConfiguration.dbUserPassword 44 | }); 45 | 46 | var charSet = 'utf8mb4'; 47 | 48 | var sql_chatting = 'CREATE TABLE IF NOT EXISTS ?? ' + 49 | '(`id` int unsigned not null AUTO_INCREMENT PRIMARY KEY, ' + 50 | '`from_uuid` char(36) not null, ' + 51 | '`to_uuid` char(36) not null, ' + 52 | '`message` text, ' + 53 | '`created_at` datetime ,' + 54 | 'INDEX from_uuid(`from_uuid`) ,' + 55 | 'INDEX to_uuid(`to_uuid`))' + 56 | 'DEFAULT CHARSET=' + charSet; 57 | 58 | connection.query(sql_chatting, tables.chattingLog, function (error, result) { 59 | // check dummy json 60 | callback && callback(databaseConfiguration, done); 61 | 62 | // close connection 63 | connection.destroy(); 64 | }); 65 | } 66 | 67 | function insertDummy(databaseConfiguration, done) { 68 | done && done(); 69 | } 70 | 71 | function insertChattingLog(connection, chatInfo, callback){ 72 | connection.query(query.insertInto, [tables.chattingLog, chatInfo], function (err, result) { 73 | callback(err, result); 74 | }); 75 | } 76 | 77 | module.exports = { 78 | deleteScheme: deleteScheme, 79 | createScheme: createScheme, 80 | insertDummy: insertDummy, 81 | writeChattingLog: insertChattingLog, 82 | option: { 83 | tables: tables, 84 | core: false 85 | } 86 | }; 87 | -------------------------------------------------------------------------------- /module/chatting/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in chatting: {}'); 5 | 6 | next(); 7 | } 8 | 9 | module.exports = { 10 | exposeLocals: exposeLocals 11 | }; -------------------------------------------------------------------------------- /module/chatting/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "selectByUUID": "SELECT ?? FROM ?? WHERE `uuid` = ?", 3 | "countAll": "SELECT count(id) as `count` FROM ??", 4 | "readChatAllLog": "SELECT ?? FROM ?? ORDER BY `id` DESC LIMIT ?, ?", 5 | "insertInto": "INSERT INTO ?? SET ?", 6 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 7 | "updateAccountById": "UPDATE ?? SET ? WHERE `id` = ?" 8 | } -------------------------------------------------------------------------------- /module/chatting/route.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | 3 | var misc = require('../../core/lib/misc'); 4 | 5 | var chatting = require('./lib/chatting'); 6 | var middleware = require('./lib/middleware'); 7 | 8 | var router = express.Router(); 9 | var routeTable = misc.getRouteData(); 10 | 11 | router.use(middleware.exposeLocals); 12 | 13 | router.get(routeTable.chat.form, chatting.index); 14 | 15 | module.exports = router; -------------------------------------------------------------------------------- /module/chatting/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "chat": { 3 | "root": "/chat", 4 | "form": "" 5 | } 6 | } -------------------------------------------------------------------------------- /module/controller_hub/description.md: -------------------------------------------------------------------------------- 1 | ## NativeBridge 2 | 3 | > Simple NativeBridge Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/controller_hub/index.js: -------------------------------------------------------------------------------- 1 | var lib = require('./lib/controller_hub'); 2 | var route = require('./route'); 3 | var middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.route = route; 7 | module.exports.middleware = middleware; 8 | -------------------------------------------------------------------------------- /module/controller_hub/lib/dummy1.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "group_title": "그룹 1", 4 | "group_subject": "구름네트웍스 경영지원팀", 5 | "group_tag": "" 6 | }, 7 | { 8 | "group_title": "IT 관리부", 9 | "group_subject": "해외망 연동 전문 부서", 10 | "group_tag": "" 11 | }, 12 | { 13 | "group_title": "테스트", 14 | "group_subject": "패킷엔진 토플로지 구성용 테스트베드", 15 | "group_tag": "192.168.x.x" 16 | } 17 | ] 18 | -------------------------------------------------------------------------------- /module/controller_hub/lib/dummy2.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "gateway_ip": "192.168.32.56", 4 | "title": "구름네트웍스 경영지원팀", 5 | "version": "PacketNgin 1.3", 6 | "installed_apps": "NetDPI,IPSec,FireWallXXX", 7 | "description": "아무말 대잔치 " 8 | }, 9 | { 10 | "gateway_ip": "192.168.32.57", 11 | "title": "구름네트웍스 RTOS 연구소", 12 | "version": "PacketNgin 1.3", 13 | "installed_apps": "NetDPI,IPSec,FireWallXXX", 14 | "description": "아무말 대잔치 " 15 | }, 16 | { 17 | "gateway_ip": "192.168.32.58", 18 | "title": "구름네트웍스 경영지원팀", 19 | "version": "PacketNgin 1.3", 20 | "installed_apps": "NetDPI,IPSec,FireWallXXX", 21 | "description": "아무말 대잔치 " 22 | } 23 | ] 24 | -------------------------------------------------------------------------------- /module/controller_hub/lib/dummy3.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "모니터링 1", 4 | "description": "네트워크 모니터, 퍼포먼스 모니터", 5 | "installed_app_id": 1 6 | }, 7 | { 8 | "title": "로드밸런싱 1", 9 | "description": "트래픽 분산, 리버스 프록시" 10 | }, 11 | { 12 | "title": "시큐리티 2", 13 | "description": "IPSec, 파이어월" 14 | }, 15 | { 16 | "title": "스위치 #1", 17 | "description": "허브, 브릿지, 릴레이" 18 | }, 19 | { 20 | "title": "라이브러리", 21 | "description": "패킷엔진, 리눅스 라이브러리" 22 | }, 23 | { 24 | "title": "드라이버", 25 | "description": "디바이스 드라이버" 26 | } 27 | ] 28 | -------------------------------------------------------------------------------- /module/controller_hub/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in controller_hub: {}'); 5 | next(); 6 | } 7 | 8 | module.exports = { 9 | exposeLocals: exposeLocals 10 | }; -------------------------------------------------------------------------------- /module/controller_hub/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "selectAll": "SELECT * FROM ?? ORDER BY `id` DESC", 3 | "selectByID": "SELECT * FROM ?? WHERE `id` = ?", 4 | "selectGatewayByID": "SELECT A.*, B.`group_title` FROM ?? A, ?? B WHERE A.`id` = ? and A.`group_id` = B.`id`", 5 | "selectRtvmByGatewayID": "SELECT A.* FROM ?? A WHERE A.`gateway_id` = ? ORDER BY `id` DESC", 6 | "insertInto": "INSERT INTO ?? SET ?" 7 | } -------------------------------------------------------------------------------- /module/controller_hub/route.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var winston = require('winston'); 3 | 4 | var misc = require('../../core/lib/misc'); 5 | 6 | var site = require('../site'); 7 | 8 | var controllerHub = require('./lib/controller_hub'); 9 | var middleware = require('./lib/middleware'); 10 | 11 | var AccountMiddleware = require('../account/lib/middleware'); 12 | 13 | var router = express.Router(); 14 | var routeTable = misc.getRouteData(); 15 | 16 | router.use(middleware.exposeLocals); 17 | 18 | // bind module router 19 | router.get(routeTable.controller_hub_root, AccountMiddleware.checkSignedIn, controllerHub.index); 20 | 21 | router.get(routeTable.controller_hub_root + routeTable.controller_hub.gateway + '/form', AccountMiddleware.checkSignedIn, controllerHub.gatewayForm); 22 | router.post(routeTable.controller_hub_root + routeTable.controller_hub.gateway + '/new', AccountMiddleware.checkSignedIn, controllerHub.newGateway); 23 | router.post(routeTable.controller_hub_root + routeTable.controller_hub.gateway + '/new-group', AccountMiddleware.checkSignedIn, controllerHub.newGatewayGroup); 24 | 25 | router.get(routeTable.controller_hub_root + routeTable.controller_hub.gateway + '/:gatewayID([0-9]+)', AccountMiddleware.checkSignedIn, controllerHub.view); 26 | router.get(routeTable.controller_hub_root + routeTable.controller_hub.gateway + '/:gatewayID([0-9]+)' + '/edit', AccountMiddleware.checkSignedIn, controllerHub.view); 27 | 28 | router.get(routeTable.controller_hub_root + routeTable.controller_hub.rtvm + '/new', AccountMiddleware.checkSignedIn, controllerHub.rtvmForm); 29 | router.post(routeTable.controller_hub_root + routeTable.controller_hub.rtvm + '/new', AccountMiddleware.checkSignedIn, controllerHub.newRtvm); 30 | 31 | router.post(routeTable.controller_hub_root + routeTable.controller_hub.rtvm + '/:rtvmID/:action', AccountMiddleware.checkSignedIn, controllerHub.rtvm); 32 | 33 | module.exports = router; 34 | -------------------------------------------------------------------------------- /module/controller_hub/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "controller_hub": { 3 | "root": "/hub", 4 | "gateway": "/gateway", 5 | "rtvm": "/rtvm", 6 | "form": "/form", 7 | "new": "/new" 8 | } 9 | } -------------------------------------------------------------------------------- /module/counter/description.md: -------------------------------------------------------------------------------- 1 | ## Counter 2 | 3 | > Global Counter Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/counter/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/counter'); 2 | const middleware = require('./lib/middleware'); 3 | 4 | module.exports = lib; 5 | module.exports.middleware = middleware; -------------------------------------------------------------------------------- /module/counter/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | var useragent = require('useragent'); 3 | 4 | var misc = require('../../../core/lib/misc'); 5 | 6 | var counter = require('./counter'); 7 | 8 | var token = misc.commonToken(); 9 | 10 | function exposeMenu(req, res, next) { 11 | 12 | next(); 13 | } 14 | 15 | function exposeLocals(req, res, next) { 16 | winston.verbose('bind locals in counter: {}'); 17 | 18 | next(); 19 | } 20 | 21 | function pageCounter(req, res, next) { 22 | var url = req.originalUrl; 23 | var method = req.method; 24 | var ip = (req.ip === '::1' || req.ip.startsWith('::ffff:')) ? '127.0.0.1' : req.ip; 25 | var ref = req.headers.referrer || req.headers.referer; 26 | var agent = useragent.parse(req.headers['user-agent']); 27 | var device = req.device; 28 | 29 | counter.insertPageCounter(url, method, ip, ref, agent, device); 30 | 31 | winston.verbose(`logged counter in counter: {page} with ${ip} ${ref || ''}`); 32 | 33 | next(); 34 | } 35 | 36 | function sessionCounter(req, res, next) { 37 | counter.session(req.sessionID, function (error, result) { 38 | if (!error && result) { 39 | var uuid; 40 | if (req.session['passport'] && req.session['passport'].user) uuid = req.session['passport'].user; 41 | 42 | counter.insertSessionLog(req['sessionID'], uuid); 43 | counter.insertSessionCounter(token.session.init); 44 | } 45 | }); 46 | 47 | next(); 48 | } 49 | 50 | module.exports = { 51 | exposeMenu: exposeMenu, 52 | exposeLocals: exposeLocals, 53 | pageCounter: pageCounter, 54 | sessionCounter: sessionCounter 55 | }; -------------------------------------------------------------------------------- /module/counter/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "insertInto": "INSERT INTO ?? SET ?", 3 | "selectByDate": "SELECT `id` as id FROM ?? WHERE `date` = ? FOR UPDATE", 4 | "selectByDateWithPath": "SELECT `id` as id FROM ?? WHERE `date` = ? and `path` = ? FOR UPDATE", 5 | "selectBySessionID": "SELECT `id` as id FROM ?? WHERE `session` = ? LIMIT 1", 6 | "updateCounterByDateWithPath": "UPDATE ?? SET `view` = `view` + 1 WHERE `date` = ? and `path` = ?", 7 | "updateCounterByDate": "UPDATE ?? SET ?? = ?? + 1 WHERE `date` = ?", 8 | "insertCounterByDateWithPath": "INSERT INTO ?? (`path`, `date`, `view`) VALUES (?, ?, 1)", 9 | "insertCounterByDate": "INSERT INTO ?? (??, `date`) VALUES (1, ?)" 10 | } -------------------------------------------------------------------------------- /module/editor/description.md: -------------------------------------------------------------------------------- 1 | ## Editor 2 | 3 | > 클라이언트 용 에디터 선택을 위한 모듈 4 | 5 | 모듈 레벨에서 클라이언트 에디터를 위한 스크립트를 제공하기 위해 준비되었습니다. 6 | 특히 npm 으로 설치되는 패키지를 bower 를 통하지 않고 클라이언트에 제공할 필요가 있을 경우 유용할 것으로 예상됩니다. 7 | 8 | ### History 9 | 10 | - 1.0.0: initial release 11 | 12 | ### Credit 13 | 14 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/editor/index.js: -------------------------------------------------------------------------------- 1 | // var route = require('./route'); 2 | // var middleware = require('./lib/middleware'); 3 | 4 | var express = require('express'); 5 | var winston = require('winston'); 6 | 7 | var router = express.Router(); 8 | 9 | // router.use(middleware.exposeLocals); 10 | 11 | router.get('/editor.js', function (req, res, next) { 12 | res.send('console.log("say hello");'); 13 | }); 14 | 15 | module.exports = { 16 | route: router, 17 | // middleware: middleware 18 | }; 19 | -------------------------------------------------------------------------------- /module/gallery/description.md: -------------------------------------------------------------------------------- 1 | ## Gallery 2 | 3 | > Global Gallery Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/gallery/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/gallery'); 2 | const { site } = require('./route'); 3 | const middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.site = site; 7 | module.exports.middleware = middleware; 8 | -------------------------------------------------------------------------------- /module/gallery/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in gallery: {}'); 5 | 6 | next(); 7 | } 8 | 9 | module.exports = { 10 | exposeLocals: exposeLocals 11 | }; -------------------------------------------------------------------------------- /module/gallery/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "insertInto": "INSERT INTO ?? SET ?", 3 | "countAll": "SELECT count(id) as `count` FROM ??", 4 | "readGalleryCategory": "SELECT * FROM ?? ORDER BY `sort`, `id` ASC", 5 | "readGalleryCategories": "SELECT * FROM ?? ORDER BY `sort`, `id` ASC", 6 | "readGalleryImageList": "SELECT * FROM ?? WHERE `category` = ? ORDER BY `sort`, `id` ASC", 7 | "readGalleryImages": "SELECT * FROM ?? ORDER BY `sort`, `id` ASC" 8 | } -------------------------------------------------------------------------------- /module/gallery/route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const misc = require('../../core/lib/misc'); 4 | const { checkManager } = require('../account/lib/middleware'); 5 | 6 | const gallery = require('./lib/gallery'); 7 | const middleware = require('./lib/middleware'); 8 | 9 | const routeTable = misc.getRouteData(); 10 | const site = express.Router(); 11 | 12 | site.use(middleware.exposeLocals); 13 | site.get(routeTable.gallery.list, gallery.images); 14 | site.post(routeTable.gallery.category, checkManager, gallery.createCategory); 15 | site.post(routeTable.gallery.image, checkManager, gallery.uploadImage); 16 | 17 | const manage = express.Router(); 18 | 19 | manage.get(routeTable.gallery.list, gallery.categoryList); 20 | manage.get(routeTable.gallery.image + '/:cate', gallery.imageList); 21 | manage.post(routeTable.gallery.upload, checkManager, gallery.createImageItem); 22 | manage.post(routeTable.gallery.upload + '/image', checkManager, gallery.uploadImage2); 23 | 24 | module.exports = { 25 | site, 26 | manage 27 | }; -------------------------------------------------------------------------------- /module/gallery/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "gallery": { 3 | "root": "/gallery", 4 | "home": "/", 5 | "list": "/", 6 | "image": "/image", 7 | "category": "/category", 8 | "control": "/control", 9 | "upload": "/upload" 10 | } 11 | } -------------------------------------------------------------------------------- /module/guestbook/description.md: -------------------------------------------------------------------------------- 1 | ## Guestbook 2 | 3 | > Global Guestbook Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/guestbook/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/guestbook'); 2 | const { site } = require('./route'); 3 | const middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.site = site; 7 | module.exports.middleware = middleware; 8 | -------------------------------------------------------------------------------- /module/guestbook/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | // res.locals.user = req.user; moved to site module 5 | 6 | winston.verbose('bind locals in guestbook: {}'); 7 | next(); 8 | } 9 | 10 | module.exports = { 11 | exposeLocals: exposeLocals 12 | }; -------------------------------------------------------------------------------- /module/guestbook/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "selectByID": "SELECT ?? FROM ?? WHERE `id` = ?", 3 | "selectByUUID": "SELECT ?? FROM ?? WHERE `uuid` = ?", 4 | "selectByUserID": "SELECT ?? FROM ?? WHERE `user_id` = ?", 5 | "countAll": "SELECT count(id) as `count` FROM ??", 6 | "readGuestbook": "SELECT ?? FROM ?? ORDER BY `id` DESC LIMIT ?, ?", 7 | "insertInto": "INSERT INTO ?? SET ?", 8 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 9 | "updateAccountByUUID": "UPDATE ?? SET ? WHERE `uuid` = ?" 10 | } -------------------------------------------------------------------------------- /module/guestbook/route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const misc = require('../../core/lib/misc'); 4 | 5 | const guestbook = require('./lib/guestbook'); 6 | const middleware = require('./lib/middleware'); 7 | 8 | const AccountMiddleware = require('../account/lib/middleware'); 9 | 10 | const site = express.Router(); 11 | const routeTable = misc.getRouteData(); 12 | 13 | site.use(middleware.exposeLocals); 14 | 15 | site.get(routeTable.guestbook.form, guestbook.guestbook); 16 | site.get(routeTable.guestbook.form + ':page', guestbook.guestbook); 17 | site.post(routeTable.guestbook.message, guestbook.registerMessage); 18 | site.post(routeTable.guestbook.reply, AccountMiddleware.checkSignedIn ,guestbook.registerReply); 19 | 20 | module.exports = { 21 | site 22 | }; 23 | -------------------------------------------------------------------------------- /module/guestbook/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "guestbook": { 3 | "root": "/guestbook", 4 | "form": "/", 5 | "message": "/register", 6 | "reply": "/register/reply", 7 | "delete": "/delete" 8 | } 9 | } -------------------------------------------------------------------------------- /module/mailgun/description.md: -------------------------------------------------------------------------------- 1 | ## Mailgun 2 | 3 | > Simple Mailgun Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/mailgun/index.js: -------------------------------------------------------------------------------- 1 | var middleware = require('./lib/middleware'); 2 | var mailgun = require('./lib/mailgun'); 3 | 4 | module.exports = mailgun; 5 | module.exports.middleware = middleware; 6 | -------------------------------------------------------------------------------- /module/mailgun/lib/database.js: -------------------------------------------------------------------------------- 1 | var mysql = require('mysql'); 2 | var winston = require('winston'); 3 | 4 | var common = require('../../../core/lib/common'); 5 | var misc = require('../../../core/lib/misc'); 6 | var databaseDefault = misc.getDatabaseDefault(); 7 | 8 | var tables = { 9 | // mailgun: databaseDefault.tablePrefix + 'mailgun' 10 | }; 11 | 12 | function deleteScheme(databaseConfiguration, callback) { 13 | callback(databaseConfiguration); 14 | } 15 | 16 | function createScheme(databaseConfiguration, callback, done) { 17 | callback && callback(databaseConfiguration, done); 18 | } 19 | 20 | function insertDummy(databaseConfiguration, done) { 21 | done && done(); 22 | } 23 | 24 | module.exports = { 25 | deleteScheme: deleteScheme, 26 | createScheme: createScheme, 27 | insertDummy: insertDummy, 28 | option: { 29 | tables: tables, 30 | core: false 31 | } 32 | }; -------------------------------------------------------------------------------- /module/mailgun/lib/mailgun.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | var path = require('path'); 3 | var winston = require('winston'); 4 | var mailgun = require('mailgun-js'); 5 | var mailcomposer = require('mailcomposer'); 6 | 7 | var common = require('../../../core/lib/common'); 8 | var misc = require('../../../core/lib/misc'); 9 | 10 | var mailgunToken = misc.serviceToken('mailgun'); 11 | var mailgunProvider = misc.serviceProvider('mailgun'); 12 | 13 | function sendMail(composer, mailer, receiver) { 14 | composer.build(function (mailBuildError, message) { 15 | var dataToSend = { 16 | to: receiver.email, 17 | message: message.toString('ascii') 18 | }; 19 | 20 | mailer.messages().sendMime(dataToSend, function (sendError, body) { 21 | if (sendError) { 22 | return winston.error(sendError); 23 | } 24 | 25 | winston.info('Sent mailgun mail to', receiver.email); 26 | }); 27 | }); 28 | } 29 | 30 | function mailgunMessage1(receiver) { 31 | var mailer = mailgun({apiKey: mailgunToken, domain: mailgunProvider}); 32 | 33 | var mailTitle = "KOSSCON 2017 사전 신청이 " + receiver.mode + " 되었습니다."; 34 | var mailSender = '"KOSSCON 관리자" '; 35 | 36 | // send updated confirm mail 37 | fs.readFile(path.join(BLITITOR.root, 'theme', BLITITOR.site.theme, 'page', 'register', 'confirm.html'), function (err, confirmHtml) { 38 | if (err) return winston.error("Can't read confirm mail html template"); 39 | 40 | fs.readFile(path.join(BLITITOR.root, 'theme', BLITITOR.site.theme, 'page', 'register', 'confirm.txt'), function (err, conformText) { 41 | if (err) return winston.error("Can't read confirm mail text template"); 42 | 43 | var composer = mailcomposer({ 44 | from: mailSender, 45 | to: receiver.email, 46 | subject: mailTitle, 47 | body: conformText.toString().replace('[[*1*]]', receiver.name).replace('[[*2*]]', receiver.mode), 48 | html: confirmHtml.toString().replace('[[*1*]]', receiver.name).replace('[[*2*]]', receiver.mode) 49 | }); 50 | 51 | // sendMail(composer, mailer, receiver); 52 | 53 | composer.build(function (mailBuildError, message) { 54 | var dataToSend = { 55 | to: receiver.email, 56 | message: message.toString('ascii') 57 | }; 58 | 59 | mailer.messages().sendMime(dataToSend, function (sendError, body) { 60 | if (sendError) { 61 | return winston.error(sendError); 62 | } 63 | 64 | winston.info('Sent mailgun mail to', receiver.email); 65 | }); 66 | }); 67 | }); 68 | }); 69 | } 70 | 71 | module.exports = { 72 | sendKossconMail: mailgunMessage1 73 | }; 74 | -------------------------------------------------------------------------------- /module/mailgun/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in mailgun: { }'); 5 | next(); 6 | } 7 | 8 | module.exports = { 9 | exposeLocals: exposeLocals 10 | }; -------------------------------------------------------------------------------- /module/manager/description.md: -------------------------------------------------------------------------------- 1 | ## Manager 2 | 3 | > Global Manager Module 4 | 5 | some description 6 | 7 | ### errata 8 | 9 | 모듈에서 제공하지 않는 url 에 대해서만 처리 10 | 기본적으로 모듈에서 관리 기능을 모두 제공하는 것으로 구현 11 | 12 | ### History 13 | 14 | - 1.0.0: initial release 15 | 16 | ### Credit 17 | 18 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/manager/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/manager'); 2 | const { site, manage } = require('./route'); 3 | const middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.site = site; 7 | module.exports.manage = manage; 8 | module.exports.middleware = middleware; -------------------------------------------------------------------------------- /module/manager/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in manager: {}'); 5 | next(); 6 | } 7 | 8 | module.exports = { 9 | exposeLocals: exposeLocals 10 | }; -------------------------------------------------------------------------------- /module/manager/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "insertInto": "INSERT INTO ?? SET ?", 3 | "selectAccountByUUID": "SELECT ?? FROM ?? auth, ?? user WHERE auth.id = user.auth_id AND user.uuid = ?", 4 | "countAllAccount": "SELECT count(auth.id) as `count` FROM ?? auth, ?? user WHERE auth.id = user.auth_id", 5 | "countAllVisitLog": "SELECT count(id) as `count` FROM ??", 6 | "countAllGuestbook": "SELECT count(id) as `count` FROM ??", 7 | "countAllGuestbookWithoutReply": "SELECT count(id) as `count` FROM ?? WHERE reply is NULL OR reply = ''", 8 | "readAccountByPage": "SELECT ?? FROM ?? auth, ?? user WHERE auth.id = user.auth_id ORDER BY auth.id DESC LIMIT ?, ?", 9 | "readGuestbookByPage": "SELECT * FROM ?? ORDER BY id DESC LIMIT ?, ?", 10 | "readGuestbookWithoutReplyByPage": "SELECT * FROM ?? WHERE reply is NULL OR reply = '' ORDER BY id DESC LIMIT ?, ?", 11 | "readVisitLogByPage": "SELECT ?? FROM ?? ORDER BY id DESC LIMIT ?, ?", 12 | "readAccountCounterByMonth": "SELECT ?? FROM ?? WHERE date LIKE ? ORDER BY `id` DESC", 13 | "readAccountCounterByDate": "SELECT ?? FROM ?? WHERE date >= ? AND date <= ? ORDER BY date DESC;", 14 | "readVisitCounter": "SELECT `path`, SUM(view) AS total FROM ?? GROUP BY `path` ORDER BY `path` ASC;", 15 | "readVisitCounterByDate": "SELECT `path`, SUM(CASE WHEN date = ? THEN view END) AS T0, SUM(CASE WHEN date = ? THEN view END) AS T1, SUM(CASE WHEN date = ? THEN view END) AS T2, SUM(CASE WHEN date = ? THEN view END) AS T3, SUM(CASE WHEN date = ? THEN view END) AS T4, SUM(CASE WHEN date = ? THEN view END) AS T5, SUM(CASE WHEN date = ? THEN view END) AS T6, SUM(CASE WHEN date = ? THEN view END) AS T7 FROM ?? GROUP BY path ORDER BY path ASC;", 16 | "readUserCounter": "SELECT SUM(view) AS total FROM ?? GROUP BY `date` ORDER BY `date` DESC LIMIT ?", 17 | "readUserCounterByDate": "SELECT SUM(CASE WHEN date = ? THEN view END) AS T0, SUM(CASE WHEN date = ? THEN view END) AS T1, SUM(CASE WHEN date = ? THEN view END) AS T2, SUM(CASE WHEN date = ? THEN view END) AS T3, SUM(CASE WHEN date = ? THEN view END) AS T4, SUM(CASE WHEN date = ? THEN view END) AS T5, SUM(CASE WHEN date = ? THEN view END) AS T6, SUM(CASE WHEN date = ? THEN view END) AS T7 FROM ?? ORDER BY date DESC;", 18 | "selectByUUID": "SELECT ?? FROM ?? WHERE `uuid` = ?", 19 | "selectByUUIDWithLimit": "SELECT ?? FROM ?? WHERE `uuid` = ? ORDER BY id DESC LIMIT ?", 20 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 21 | "deleteByID": "DELETE FROM ?? WHERE `id` = ?", 22 | "updateAccountByUUID": "UPDATE ?? SET ? WHERE `uuid` = ?", 23 | "countAllGalleryCategory": "SELECT count(id) as `count` FROM ??", 24 | "readGalleryCategoryByPage": "SELECT * FROM ?? ORDER BY sort, id ASC LIMIT ?, ?", 25 | "readGalleryImageList": "SELECT * FROM ?? WHERE `category` = ? ORDER BY sort, id ASC", 26 | "updateGalleryImageSortOrder": "UPDATE ?? SET ? WHERE `category` = ? AND `id` = ?", 27 | "readReservationStatus": "SELECT * FROM ?? WHERE `category` = ? ORDER BY `sort`, `updated_at`, `id` ASC", 28 | "readReservationList": "SELECT * FROM ?? WHERE `category` = ? ORDER BY `updated_at` DESC", 29 | "countAllReservationList": "SELECT count(id) as `count` FROM ?? WHERE `category` = ?", 30 | "readReservationListByPage": "SELECT * FROM ?? WHERE `category` = ? ORDER BY `updated_at` DESC LIMIT ?, ?", 31 | "readTutorialStatusList": "SELECT * from ?? WHERE `category` = ? and FIND_IN_SET(?, `status`)" 32 | } -------------------------------------------------------------------------------- /module/manager/route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const winston = require('winston'); 3 | 4 | const misc = require('../../core/lib/misc'); 5 | 6 | const manager = require('./lib/manager'); 7 | const middleware = require('./lib/middleware'); 8 | 9 | const Account = require('../account'); 10 | const Notice = require('../notice'); 11 | const Reservation = require('../reservation'); 12 | 13 | const routeTable = misc.getRouteData(); 14 | const site = express.Router(); 15 | 16 | site.use(Account.middleware.exposeLocals); 17 | 18 | site.get(routeTable.manage['login'], manager.loginForm); 19 | site.post(routeTable.manage['login'], manager.loginProcess); 20 | 21 | const manage = express.Router(); 22 | 23 | manage.use(Account.middleware.checkManager); 24 | 25 | manage.get(routeTable.manage['home'], manager.index); 26 | manage.get(routeTable.manage['dashboard'], manager.dashboard); // for ajax dashboard 27 | // for counter 28 | manage.get(routeTable.manage['page_log'], manager.pageViewLog); 29 | manage.get(routeTable.manage['page_counter'], manager.pageViewCounter); 30 | // for account 31 | manage.get(routeTable.manage['account'], manager.accountList); 32 | manage.get(routeTable.manage['account_counter'], manager.accountActionCounter); 33 | 34 | //todo: move each module features to module's router. like this. 35 | manage.use(routeTable.notice.root, Notice.manage); 36 | manage.use(routeTable.reservation.root, Reservation.manage); 37 | 38 | //todo: update like notice module 39 | manage.get(routeTable.manage.tutorial, manager.reservationStatus); 40 | manage.get(routeTable.manage.tutorialStatus, manager.reservationTutorialStatus); 41 | 42 | // for guestbook 43 | manage.get(routeTable.guestbook.root, manager.guestbookList); 44 | manage.post(routeTable.guestbook.root + routeTable.guestbook.reply, manager.guestbookReply); 45 | manage.post(routeTable.guestbook.root + routeTable.guestbook.delete, manager.guestbookDelete); 46 | // for gallery 47 | manage.get(routeTable.manage.gallery, manager.galleryManager); 48 | manage.post(routeTable.manage.galleryImageSort, manager.galleryImageSort); 49 | manage.post(routeTable.manage.galleryImageRemove, manager.galleryImageDelete); 50 | manage.post(routeTable.manage.galleryCategory, manager.galleryCategory); 51 | manage.get(routeTable.manage.galleryImage, manager.galleryImageList); 52 | 53 | module.exports = { 54 | site, 55 | manage 56 | }; 57 | -------------------------------------------------------------------------------- /module/manager/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "manage": { 3 | "root": "/manage", 4 | "login": "/login", 5 | "home": "/", 6 | "dashboard": "/dashboard", 7 | "account": "/account", 8 | "tutorial": "/tutorial", 9 | "tutorialStatus": "/reservation/tutorial/status", 10 | "guestbook": "/guestbook", 11 | "gallery": "/gallery", 12 | "galleryCategory": "/gallery/category", 13 | "galleryImage": "/gallery/image", 14 | "galleryImageSort": "/gallery/image/sort", 15 | "galleryImageRemove": "/gallery/image/remove", 16 | "page_log": "/page/log", 17 | "pageView": "/page", 18 | "page_counter": "/counter/page", 19 | "account_counter": "/counter/account" 20 | } 21 | } -------------------------------------------------------------------------------- /module/notice/description.md: -------------------------------------------------------------------------------- 1 | ## Site 2 | 3 | > Simple notice board Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/notice/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/notice'); 2 | const { site, manage } = require('./route'); 3 | const middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.site = site; 7 | module.exports.manage = manage; 8 | module.exports.middleware = middleware; 9 | -------------------------------------------------------------------------------- /module/notice/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in notice: {}'); 5 | 6 | next(); 7 | } 8 | 9 | module.exports = { 10 | exposeLocals: exposeLocals 11 | }; -------------------------------------------------------------------------------- /module/notice/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "insertInto": "INSERT INTO ?? SET ?", 3 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 4 | "deleteByID": "DELETE FROM ?? WHERE `id` = ?", 5 | "selectByID": "SELECT ?? FROM ?? WHERE `id` = ?", 6 | "selectByIDs": "SELECT * FROM ?? WHERE `id` in (?)", 7 | "countAll": "SELECT count(id) AS `count` FROM ??", 8 | "readNoticeList": "SELECT * FROM ?? WHERE `category` = ? ORDER BY `updated_at` ASC", 9 | "readNoticeListByPage": "SELECT ?? FROM ?? where `category` = ? ORDER BY id DESC LIMIT ?, ?", 10 | "readNoticeListByPageWithAuthor": "SELECT ?? FROM ?? AS A, ?? AS B where `category` = ? and A.`user_id` = B.`auth_id` ORDER BY A.id DESC LIMIT ?, ?", 11 | "selectByIdentifier": "SELECT * FROM ?? WHERE `category` = ? and `name` = ? and `email` = ? and `phone` = ?", 12 | "anyAuthor": "SELECT ?? FROM ?? WHERE INSTR(`grant`, ?) ORDER BY `id` ASC LIMIT 1" 13 | } -------------------------------------------------------------------------------- /module/notice/route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const misc = require('../../core/lib/misc'); 4 | const { checkManager } = require('../account/lib/middleware'); 5 | 6 | const notice = require('./lib/notice'); 7 | const middleware = require('./lib/middleware'); 8 | 9 | const routeTable = misc.getRouteData(); 10 | const site = express.Router(); 11 | 12 | site.use(middleware.exposeLocals); 13 | site.get(routeTable.notice.list, notice.list); 14 | site.post(routeTable.notice.list, checkManager, notice.control); 15 | site.get(routeTable.notice.update + '/:id', checkManager, notice.updateForm); 16 | site.post(routeTable.notice.update + '/:id', checkManager, notice.update); 17 | site.get(routeTable.notice.write, checkManager, notice.writeForm); 18 | site.post(routeTable.notice.write, checkManager, notice.write); 19 | 20 | const manage = express.Router(); 21 | 22 | manage.get(routeTable.notice.manage, notice.manageHome); 23 | manage.post(routeTable.notice.manage, notice.manage); 24 | 25 | module.exports = { site, manage }; -------------------------------------------------------------------------------- /module/notice/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "notice": { 3 | "root": "/notice", 4 | "list": "/", 5 | "view": "/view", 6 | "write": "/write", 7 | "update": "/update", 8 | "delete": "/delete", 9 | "feedback": "/write/feedback", 10 | "manage": "/" 11 | } 12 | } -------------------------------------------------------------------------------- /module/reservation/description.md: -------------------------------------------------------------------------------- 1 | ## Site 2 | 3 | > Simple Reservation Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/reservation/index.js: -------------------------------------------------------------------------------- 1 | const lib = require('./lib/reservation'); 2 | const { site, manage } = require('./route'); 3 | const middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.site = site; 7 | module.exports.manage = manage; 8 | module.exports.middleware = middleware; 9 | -------------------------------------------------------------------------------- /module/reservation/lib/dummy_status.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "category": 1, 4 | "title": "Rust 프로젝트 컨트리뷰션", 5 | "sub_title": "서상현", 6 | "counter": 0, 7 | "max_count": 30 8 | }, 9 | { 10 | "category": 1, 11 | "title": "오픈소스를 활용한 채팅서비스 개발사례", 12 | "sub_title": "정진영", 13 | "counter": 0, 14 | "max_count": 30 15 | }, 16 | { 17 | "category": 1, 18 | "title": "루씬 쏠라 검색 방법론 튜토리얼 및 실습", 19 | "sub_title": "강명구", 20 | "counter": 0, 21 | "max_count": 30 22 | }, 23 | { 24 | "category": 1, 25 | "title": "Loopback 으로 API 서버 만들어보기", 26 | "sub_title": "김정근", 27 | "counter": 0, 28 | "max_count": 30 29 | }, 30 | { 31 | "category": 1, 32 | "title": "디자이너 없이 SpringBoot 프로젝트 제대로 만들기", 33 | "sub_title": "장기영", 34 | "counter": 0, 35 | "max_count": 30 36 | }, 37 | { 38 | "category": 1, 39 | "title": "Cocos2d-x Quick Start", 40 | "sub_title": "박현천", 41 | "counter": 0, 42 | "max_count": 30 43 | }, 44 | { 45 | "category": 1, 46 | "title": "Docker 를 이용한 php 개발 환경 구축하기", 47 | "sub_title": "황재희", 48 | "counter": 0, 49 | "max_count": 30 50 | }, 51 | { 52 | "category": 1, 53 | "title": "Linux Kernel - perf 오픈소스 참여방법과 개발과정의 이해", 54 | "sub_title": "송태웅", 55 | "counter": 0, 56 | "max_count": 30 57 | }, 58 | { 59 | "category": 1, 60 | "title": "React + Redux 앱 만들기", 61 | "sub_title": "채수원", 62 | "counter": 0, 63 | "max_count": 30 64 | }, 65 | { 66 | "category": 1, 67 | "title": "Unity 와 클라우드 연동으로 하루만에 끝내는 모바일 게임 만들기", 68 | "sub_title": "홍윤석,이정엽", 69 | "counter": 0, 70 | "max_count": 30 71 | }, 72 | { 73 | "category": 1, 74 | "title": "제로부터 시작하는 텐서플로우", 75 | "sub_title": "조만석", 76 | "counter": 0, 77 | "max_count": 30 78 | }, 79 | { 80 | "category": 1, 81 | "title": "고 언어를 사용한 임베디드 리눅스 프로그래밍", 82 | "sub_title": "이호민", 83 | "counter": 0, 84 | "max_count": 30 85 | } 86 | ] -------------------------------------------------------------------------------- /module/reservation/lib/manager.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | 3 | var common = require('../../../core/lib/common'); 4 | var misc = require('../../../core/lib/misc'); 5 | 6 | function registerManager(phone) { 7 | var smsToken = misc.serviceToken('sms_api'); 8 | var smsProvider = 'http://api.apistore.co.kr/ppurio/2/sendnumber/save/kosslab'; 9 | 10 | request({ 11 | uri: smsProvider, 12 | method: 'POST', 13 | headers: { 14 | 'Content-Type': 'application/x-www-form-urlencoded', 15 | 'x-waple-authorization': smsToken 16 | }, 17 | encoding: 'utf8', 18 | json: true, 19 | formData: { 20 | sendnumber: phone, 21 | comment: 'manager2018', 22 | pintype: 'SMS', 23 | pincode: '234822' 24 | } 25 | }, function (error, response, body) { 26 | console.log(body) 27 | if (response.statusCode == 200 && body['result_code'] == '200') { 28 | console.log({ 29 | "status": "success", 30 | "data": { 31 | "phone": phone 32 | } 33 | }); 34 | } else { 35 | console.error('register sms manager to ' + phone); 36 | 37 | console.log({ 38 | "status": "fail", 39 | "data": { 40 | "phone": phone 41 | } 42 | }); 43 | } 44 | }); 45 | } 46 | 47 | registerManager('01045151082') 48 | -------------------------------------------------------------------------------- /module/reservation/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in reservation: {}'); 5 | 6 | next(); 7 | } 8 | 9 | module.exports = { 10 | exposeLocals: exposeLocals 11 | }; -------------------------------------------------------------------------------- /module/reservation/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "insertInto": "INSERT INTO ?? SET ?", 3 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 4 | "selectByIDs": "SELECT * FROM ?? WHERE `id` in (?)", 5 | "increaseStatusByID": "UPDATE ?? SET counter = counter + 1 WHERE `id` = ?", 6 | "decreaseStatusByID": "UPDATE ?? SET counter = counter - 1 WHERE `id` = ? and counter > 0", 7 | "countAll": "SELECT count(id) as `count` FROM ??", 8 | "readReservationStatus": "SELECT * FROM ?? WHERE `category` = ? ORDER BY `sort`, `updated_at`, `id` ASC", 9 | "readReservationList": "SELECT * FROM ?? WHERE `category` = ? ORDER BY `updated_at` ASC", 10 | "selectByIdentifier": "SELECT * FROM ?? WHERE `category` = ? and `name` = ? and `email` = ? and `phone` = ?", 11 | "countAllReservationList": "SELECT count(id) as `count` FROM ?? WHERE `category` = ?", 12 | "readReservationListByPage": "SELECT * FROM ?? WHERE `category` = ? ORDER BY `updated_at` DESC LIMIT ?, ?", 13 | "readTutorialStatusList": "SELECT * from ?? WHERE `category` = ? and FIND_IN_SET(?, `status`)" 14 | } -------------------------------------------------------------------------------- /module/reservation/route.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const misc = require('../../core/lib/misc'); 4 | 5 | const reservation = require('./lib/reservation'); 6 | const middleware = require('./lib/middleware'); 7 | 8 | const routeTable = misc.getRouteData(); 9 | const site = express.Router(); 10 | 11 | site.use(middleware.exposeLocals); 12 | 13 | site.get(routeTable.reservation['form'] + '/:cate?', reservation.form); 14 | site.post(routeTable.reservation['form'], reservation.register); 15 | site.get(routeTable.reservation['status'], reservation.status); 16 | site.post(routeTable.reservation['phone_secret'], reservation.sendSecret); 17 | 18 | const manage = express.Router(); 19 | 20 | manage.get(routeTable.reservation['manage'], reservation.manageHome); 21 | manage.post(routeTable.reservation['manage'], reservation.manage); 22 | manage.get(routeTable.reservation['clean_list'], reservation.manageFullList); 23 | 24 | module.exports = { site, manage }; -------------------------------------------------------------------------------- /module/reservation/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "reservation": { 3 | "root": "/reservation", 4 | "form": "", 5 | "status": "/status", 6 | "phone_secret": "/secret", 7 | "manage": "/", 8 | "clean_list": "/clean" 9 | } 10 | } -------------------------------------------------------------------------------- /module/site/description.md: -------------------------------------------------------------------------------- 1 | ## Reservation 2 | 3 | > Default Site Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/site/index.js: -------------------------------------------------------------------------------- 1 | var lib = require('./lib/site'); 2 | var middleware = require('./lib/middleware'); 3 | 4 | module.exports = lib; 5 | module.exports.middleware = middleware; 6 | -------------------------------------------------------------------------------- /module/site/lib/middleware.js: -------------------------------------------------------------------------------- 1 | const winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | // res.locals.user = req.user; 5 | res.locals.message = req.flash(); 6 | 7 | winston.verbose('bind locals in site: {message}'); 8 | next(); 9 | } 10 | 11 | function cacheControl(req, res, next) { 12 | if (!BLITITOR.config['cacheControl']) { // to distinguish by global middleware 13 | res.set({ 14 | 'Cache-Control': 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0', 15 | 'Pragma': 'no-cache' 16 | }); 17 | } 18 | 19 | next(); 20 | } 21 | 22 | module.exports = { 23 | exposeLocals: exposeLocals, 24 | cacheControl: cacheControl, 25 | }; -------------------------------------------------------------------------------- /module/site/lib/site.js: -------------------------------------------------------------------------------- 1 | const util = require('util'); 2 | const winston = require('winston'); 3 | const misc = require('../../../core/lib/misc'); 4 | const common = require('../../../core/lib/common'); 5 | 6 | const filter = common.regexFilter(); 7 | 8 | function plainPage(req, res) { 9 | 10 | const params = { 11 | path: req.path, 12 | page_id: req.path === '/' ? 'index' : req.path.match(filter.page)[1].replace(/-/g, '_'), 13 | }; 14 | 15 | params.title = misc.getPageName(res.locals.siteMenu, params.page_id); 16 | 17 | //500 Error 18 | //throw Error('make noise!'); 19 | 20 | // winston.info(req.path, params, req.path.match(filter.page)); 21 | 22 | res.render(BLITITOR.site.theme + '/page/' + params.page_id, params); 23 | } 24 | 25 | function plainPageWithSubPath(req, res) { 26 | 27 | const params = { 28 | path: req.path, 29 | page_id: req.path.lastIndexOf('/') === req.path.toString().length - 1 ? req.path.replace(/-/g, '_') + 'index' : req.path.replace(/-/g, '_'), 30 | }; 31 | 32 | params.title = misc.getPageName(res.locals.siteMenu, params.page_id, true); 33 | 34 | // winston.info(req.path, params, req.path.match(filter.page)); 35 | // console.log(req.path.lastIndexOf('/'), req.path.toString().length -1 ); 36 | // console.log(params.page_id); 37 | 38 | res.render(BLITITOR.site.theme + '/page' + params.page_id, params); 39 | } 40 | 41 | function bindSiteMenuToRouter(menu, router) { 42 | menu.SiteMenu.map(function (item) { 43 | winston.verbose('Bound static menu:' + util.inspect(item).split('\n').map(i => i.trim()).join(' ')); 44 | if (!item.useSubPath) item.useSubPath = false; 45 | 46 | router[item['type'] || 'get'](item['url'], !item.useSubPath ? plainPage : plainPageWithSubPath); 47 | }); 48 | } 49 | 50 | function redirectPage(url) { 51 | return function (req, res) { 52 | winston.warn('redirect to', url || 'back'); 53 | if (url) { 54 | res.redirect(url); 55 | } else { 56 | res.redirect('back'); 57 | } 58 | }; 59 | } 60 | 61 | function exposeAppLocals(locals, menu) { 62 | return function (req, res, next) { 63 | res.locals.app = locals; 64 | res.locals.siteMenu = menu.SiteMenu || {}; 65 | //todo: Menu object by menu array 66 | // res.locals.Menu = misc.makeMenuObject(menu) to object 67 | res.locals.adminMenu = menu.AdminMenu || {}; 68 | res.locals.manageMenu = menu.ManageMenu || {}; 69 | 70 | winston.verbose('bind locals in app: {app, menu}'); 71 | next(); 72 | } 73 | } 74 | 75 | module.exports = { 76 | redirect: redirectPage, 77 | bindMenu: bindSiteMenuToRouter, 78 | exposeAppLocals: exposeAppLocals, 79 | }; 80 | -------------------------------------------------------------------------------- /module/slack/description.md: -------------------------------------------------------------------------------- 1 | ## Slack 2 | 3 | > Simple Slack Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/slack/index.js: -------------------------------------------------------------------------------- 1 | var middleware = require('./lib/middleware'); 2 | var slack = require('./lib/slack'); 3 | 4 | module.exports = slack; 5 | module.exports.middleware = middleware; 6 | -------------------------------------------------------------------------------- /module/slack/lib/database.js: -------------------------------------------------------------------------------- 1 | var mysql = require('mysql'); 2 | var winston = require('winston'); 3 | 4 | var common = require('../../../core/lib/common'); 5 | var misc = require('../../../core/lib/misc'); 6 | var databaseDefault = misc.getDatabaseDefault(); 7 | 8 | var tables = { 9 | // slack: databaseDefault.tablePrefix + 'slack' 10 | }; 11 | 12 | function deleteScheme(databaseConfiguration, callback) { 13 | callback(databaseConfiguration); 14 | } 15 | 16 | function createScheme(databaseConfiguration, callback, done) { 17 | callback && callback(databaseConfiguration, done); 18 | } 19 | 20 | function insertDummy(databaseConfiguration, done) { 21 | done && done(); 22 | } 23 | 24 | module.exports = { 25 | deleteScheme: deleteScheme, 26 | createScheme: createScheme, 27 | insertDummy: insertDummy, 28 | option: { 29 | tables: tables, 30 | core: false 31 | } 32 | }; -------------------------------------------------------------------------------- /module/slack/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | winston.verbose('bind locals in slack: { }'); 5 | next(); 6 | } 7 | 8 | module.exports = { 9 | exposeLocals: exposeLocals 10 | }; -------------------------------------------------------------------------------- /module/slack/lib/slack.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | var request = require('superagent'); 3 | 4 | var common = require('../../../core/lib/common'); 5 | var misc = require('../../../core/lib/misc'); 6 | 7 | var slackToken = misc.serviceToken('slack'); 8 | var slackProvider = misc.serviceProvider('slack'); 9 | 10 | function sendSlackMessage(message, channel) { 11 | var slackAPI = { 12 | "uri": slackProvider, 13 | "token": slackToken, 14 | "channel": channel 15 | }; 16 | 17 | request 18 | .post(slackAPI.uri) 19 | .type('form') 20 | .send({ 21 | token: slackAPI.token, 22 | channel: slackAPI.channel, 23 | text: message}) 24 | .end(function (error, response) { 25 | // Calling the end function will send the request 26 | if (error || !response.body.ok) console.log(error, response.body.ok); 27 | }); 28 | } 29 | 30 | module.exports = { 31 | sendMessage: sendSlackMessage 32 | }; 33 | -------------------------------------------------------------------------------- /module/teamblog/description.md: -------------------------------------------------------------------------------- 1 | ## Teamblog 2 | 3 | > Simple Teamblog Module 4 | 5 | some description 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /module/teamblog/index.js: -------------------------------------------------------------------------------- 1 | var lib = require('./lib/teamblog'); 2 | var route = require('./route'); 3 | var middleware = require('./lib/middleware'); 4 | 5 | module.exports = lib; 6 | module.exports.route = route; 7 | module.exports.middleware = middleware; 8 | -------------------------------------------------------------------------------- /module/teamblog/lib/middleware.js: -------------------------------------------------------------------------------- 1 | var winston = require('winston'); 2 | 3 | function exposeLocals(req, res, next) { 4 | // res.locals.user = req.user; moved to site module 5 | 6 | winston.verbose('bind locals in teamblog: {}'); 7 | next(); 8 | } 9 | 10 | module.exports = { 11 | exposeLocals: exposeLocals 12 | }; -------------------------------------------------------------------------------- /module/teamblog/lib/query.json: -------------------------------------------------------------------------------- 1 | { 2 | "selectByID": "SELECT ?? FROM ?? WHERE `id` = ? LIMIT 1", 3 | "selectByURL": "SELECT ?? FROM ?? WHERE `custom_url` = ? ORDER BY `id` DESC LIMIT 1 ", 4 | "selectByUUID": "SELECT ?? FROM ?? WHERE `user_uuid` = ?", 5 | "selectByUserID": "SELECT ?? FROM ?? WHERE `user_id` = ?", 6 | "countAll": "SELECT count(id) as `count` FROM ??", 7 | "countAllGroupByMonth": "SELECT month(??) as `month`, year(??) as `year`, count(`id`) as `count` FROM ?? GROUP BY month(??), year(??) ORDER BY ?? DESC", 8 | "readTeamblogByTagAll": "SELECT a.* FROM ?? as b, ?? as c LEFT JOIN ?? as a ON a.`id` = c.`tag_related_post_id` WHERE b.`tag` = ? and b.`id` = c.`tag_id` ORDER BY a.`id` DESC", 9 | "readTeamblogByPage": "SELECT ?? FROM ?? ORDER BY `id` DESC LIMIT ?, ?", 10 | "readTeamblogMonthlyAll": "SELECT ?? FROM ?? WHERE YEAR(??) = ? AND MONTH(??) = ? ORDER BY `id` DESC", 11 | "readTeamblogRecently": "SELECT ?? FROM ?? ORDER BY `id` DESC LIMIT ?", 12 | "readTeamblogPinned": "SELECT ?? FROM ?? WHERE `pinned` = ? ORDER BY `id` DESC LIMIT ?", 13 | "selectTagByPost": "select ??, ?? from ?? as a, ?? as b, ?? as c where a.`id` = ? and a.`id` = b.`tag_related_post_id` and b.`tag_id` = c.`id`", 14 | "updateCounterByTag": "UPDATE ?? SET ?? = ?? + 1 WHERE `tag` = ?", 15 | "selectByTag": "SELECT `id`, `tag` FROM ?? WHERE `tag` = ? FOR UPDATE", 16 | "insertInto": "INSERT INTO ?? SET ?", 17 | "updateByID": "UPDATE ?? SET ? WHERE `id` = ?", 18 | "anyAuthor": "SELECT ?? FROM ?? ORDER BY `id` ASC LIMIT 1" 19 | } -------------------------------------------------------------------------------- /module/teamblog/route.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | 3 | var misc = require('../../core/lib/misc'); 4 | 5 | var teamblog = require('./lib/teamblog'); 6 | var middleware = require('./lib/middleware'); 7 | 8 | var AccountMiddleware = require('../account/lib/middleware'); 9 | 10 | var router = express.Router(); 11 | var routeTable = misc.getRouteData(); 12 | 13 | router.use(middleware.exposeLocals); 14 | 15 | router.get(routeTable.teamblog.post + '/:postNumber([0-9]+)', teamblog.view); 16 | router.get(routeTable.teamblog.post + '/:postTitle', teamblog.view); 17 | 18 | router.get(routeTable.teamblog.write, AccountMiddleware.checkSignedIn, teamblog.write); // in order to avoid conflict with `:page` params 19 | router.post(routeTable.teamblog.write, AccountMiddleware.checkSignedIn, teamblog.save); 20 | 21 | router.get('/', teamblog.list); 22 | router.get(routeTable.teamblog.list, teamblog.list); 23 | router.get(routeTable.teamblog.list + ':page([0-9]+)', teamblog.list); 24 | router.get(routeTable.teamblog.list + ':year([0-9]+)/:month([0-9]+)', teamblog.list); 25 | router.get(routeTable.teamblog.tag.list + '/:tag' , teamblog.list); 26 | 27 | module.exports = router; 28 | -------------------------------------------------------------------------------- /module/teamblog/route.json: -------------------------------------------------------------------------------- 1 | { 2 | "teamblog": { 3 | "root": "/blog", 4 | "list": "/", 5 | "write": "/write", 6 | "post": "/post", 7 | "tag": { 8 | "list": "/tag" 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blititer", 3 | "version": "0.5.0", 4 | "private": true, 5 | "engines": { 6 | "node": "~4.2.1 || ~0.12.0", 7 | "iojs": ">=1.2.0" 8 | }, 9 | "dependencies": { 10 | "@flowjs/flow.js": "^2.13.1", 11 | "bcryptjs": "^2.4.3", 12 | "body-parser": "^1.18.3", 13 | "bootstrap": "^4.1.3", 14 | "bulma": "^0.7.2", 15 | "bulma-extensions": "^4.0.0", 16 | "cli-color": "^1.4.0", 17 | "compression": "^1.7.3", 18 | "connect-flash": "^0.1.1", 19 | "cookie-parser": "^1.4.3", 20 | "errorhandler": "^1.5.0", 21 | "express": "^4.16.4", 22 | "express-device": "^0.4.2", 23 | "express-mysql-session": "^2.0.1", 24 | "express-routemap": "^1.1.0", 25 | "express-session": "^1.15.6", 26 | "express-status-monitor": "^1.2.3", 27 | "express-validator": "^5.3.0", 28 | "font-awesome": "^4.7.0", 29 | "jimp": "^0.5.6", 30 | "jquery": "^3.3.1", 31 | "lusca": "^1.6.1", 32 | "mailcomposer": "^4.0.2", 33 | "mailgun-js": "^0.22.0", 34 | "markdown-it": "^8.4.2", 35 | "method-override": "^3.0.0", 36 | "minimist": "^1.2.0", 37 | "mkdirp": "^0.5.1", 38 | "moment": "^2.22.2", 39 | "morgan": "^1.9.1", 40 | "multer": "^1.4.1", 41 | "mysql": "^2.16.0", 42 | "neo-async": "^2.6.0", 43 | "nunjucks": "^3.1.4", 44 | "passport": "^0.4.0", 45 | "passport-local": "^1.0.0", 46 | "popper.js": "^1.14.6", 47 | "prompt": "^1.0.0", 48 | "purecss": "^1.0.0", 49 | "quilljs-renderer": "0.0.8", 50 | "remove-markdown": "^0.3.0", 51 | "request": "^2.88.0", 52 | "semver": "^5.6.0", 53 | "serve-favicon": "^2.5.0", 54 | "sharp": "^0.21.0", 55 | "socket.io": "^2.1.1", 56 | "striptags": "^3.1.1", 57 | "superagent": "^4.0.0-beta.5", 58 | "useragent": "^2.3.0", 59 | "uuid": "^3.3.2", 60 | "winston": "^3.1.0" 61 | }, 62 | "scripts": { 63 | "dev": "nodemon core/index.js", 64 | "prepare": "node core/setup.js all", 65 | "setup": "node core/setup.js", 66 | "start": "node core/index.js", 67 | "prod": "echo \"set production\" && exit 0", 68 | "test": "echo \"Error: no test specified\" && exit 1" 69 | }, 70 | "devDependencies": { 71 | "express-print-routes": "^1.0.0" 72 | }, 73 | "description": "Old School Web Site Template for All Web Agencies and Developers", 74 | "main": "core/index.js", 75 | "directories": { 76 | "doc": "docs" 77 | }, 78 | "repository": { 79 | "type": "git", 80 | "url": "git+https://github.com/soomtong/blititor.git" 81 | }, 82 | "keywords": [ 83 | "blititor", 84 | "web", 85 | "service", 86 | "template" 87 | ], 88 | "author": "soomtong@gmail.com", 89 | "license": "MIT", 90 | "bugs": { 91 | "url": "https://github.com/soomtong/blititor/issues" 92 | }, 93 | "homepage": "https://github.com/soomtong/blititor#readme" 94 | } 95 | -------------------------------------------------------------------------------- /public/common/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/public/common/favicon.ico -------------------------------------------------------------------------------- /theme/furion/_include/footer.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /theme/furion/_include/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Furion Blog 6 | 7 | 8 | 11 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /theme/furion/_include/menu.html: -------------------------------------------------------------------------------- 1 | {% import './menu_item.html' as Menu %} 2 | 26 | -------------------------------------------------------------------------------- /theme/furion/_include/menu_item.html: -------------------------------------------------------------------------------- 1 | {% macro item(item, site) %} 2 | 5 | {% endmacro %} 6 | {% macro itemGranted(item, site) %} 7 | 10 | {% endmacro %} -------------------------------------------------------------------------------- /theme/furion/common/asset/andrew-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/furion/common/asset/andrew-avatar.png -------------------------------------------------------------------------------- /theme/furion/common/asset/ericf-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/furion/common/asset/ericf-avatar.png -------------------------------------------------------------------------------- /theme/furion/common/asset/reid-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/furion/common/asset/reid-avatar.png -------------------------------------------------------------------------------- /theme/furion/common/asset/tilo-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/furion/common/asset/tilo-avatar.png -------------------------------------------------------------------------------- /theme/furion/common/pagination.css: -------------------------------------------------------------------------------- 1 | nav[role="navigation"] { 2 | text-align: center; 3 | } 4 | 5 | .cd-pagination { 6 | width: 90%; 7 | max-width: 768px; 8 | margin: 2em auto 4em; 9 | text-align: center; 10 | } 11 | .cd-pagination li { 12 | /* hide numbers on small devices */ 13 | display: none; 14 | margin: .2em; 15 | } 16 | .cd-pagination li.button { 17 | /* make sure prev next buttons are visible */ 18 | display: inline-block; 19 | } 20 | .cd-pagination a, .cd-pagination span { 21 | display: inline-block; 22 | -webkit-user-select: none; 23 | -moz-user-select: none; 24 | -ms-user-select: none; 25 | user-select: none; 26 | /* use padding and font-size to change buttons size */ 27 | padding: .5em .8em; 28 | /*font-size: 1.6rem;*/ 29 | text-decoration: none; 30 | } 31 | .cd-pagination a { 32 | border: 1px solid #e6e6e6; 33 | border-radius: 0.25em; 34 | } 35 | .no-touch .cd-pagination a:hover { 36 | background-color: #f2f2f2; 37 | } 38 | .cd-pagination a:active { 39 | /* click effect */ 40 | -webkit-transform: scale(0.9); 41 | -moz-transform: scale(0.9); 42 | -ms-transform: scale(0.9); 43 | -o-transform: scale(0.9); 44 | transform: scale(0.9); 45 | } 46 | .cd-pagination a.disabled { 47 | /* button disabled */ 48 | color: rgba(46, 64, 87, 0.4); 49 | pointer-events: none; 50 | } 51 | .cd-pagination a.disabled::before, .cd-pagination a.disabled::after { 52 | opacity: .4; 53 | } 54 | .cd-pagination .button:first-of-type a::before { 55 | content: '\00ab '; 56 | } 57 | .cd-pagination .button:last-of-type a::after { 58 | content: ' \00bb'; 59 | } 60 | .cd-pagination .current { 61 | /* selected number */ 62 | background-color: #64a281; 63 | border-color: #64a281; 64 | color: #ffffff; 65 | pointer-events: none; 66 | } 67 | @media only screen and (min-width: 768px) { 68 | .cd-pagination li { 69 | display: inline-block; 70 | } 71 | } 72 | @media only screen and (min-width: 1170px) { 73 | .cd-pagination { 74 | margin: 4em auto 6em; 75 | } 76 | } -------------------------------------------------------------------------------- /theme/furion/common/style.css: -------------------------------------------------------------------------------- 1 | .post .post-title a { 2 | color: #303030; 3 | } 4 | .post .post-title a:hover { 5 | color: #202020; 6 | } 7 | .post .post-date { 8 | margin: auto .5em; 9 | } 10 | .post-category-1 { 11 | background: #5aba59; 12 | } 13 | .post-category-2 { 14 | background: #4d85d1; 15 | } 16 | .post-category-3 { 17 | background: #8156a7; 18 | } 19 | .post-category-4 { 20 | background: #df2d4f; 21 | } 22 | .post-description { 23 | margin-top: 1.5em; 24 | } 25 | .post-description .post-image-meta h3 { 26 | margin-top: 0.5em; 27 | } 28 | .post textarea { 29 | min-height: 300px; 30 | max-height: 500px; 31 | overflow-y: auto; 32 | } 33 | .post span.small { 34 | font-size: 0.8em; 35 | } 36 | .alert { 37 | padding: 1em; 38 | margin: .5em 0; 39 | } 40 | .alert-login { 41 | color: #ffffff; 42 | border: 1px solid #DF7514; 43 | background: #DF7514; 44 | } 45 | .label { 46 | margin: 0 0.1em; 47 | padding: 0.3em 1em; 48 | color: #fff; 49 | background: #999; 50 | font-size: 80%; 51 | } 52 | .label-design { 53 | background: #5aba59; 54 | } 55 | .label-pure { 56 | background: #4d85d1; 57 | } 58 | .label-help { 59 | background: #8156a7; 60 | } 61 | .label-info { 62 | background: #df2d4f; 63 | } 64 | .textarea-holder { 65 | position: relative; 66 | } 67 | 68 | .web-editor { 69 | line-height: 1.5; 70 | padding: 1.2em 1em; 71 | width: 100%; 72 | min-height: 300px; 73 | max-height: 500px; 74 | overflow-y: auto; 75 | 76 | border: 1px solid #ccc; 77 | box-shadow: inset 0 1px 3px #ddd; 78 | border-radius: 4px; 79 | box-sizing: border-box; 80 | 81 | color: #ffffff; 82 | text-shadow: 0 0 0 #1e1e1e; 83 | -webkit-text-fill-color: transparent; 84 | } 85 | .tail { 86 | position: absolute; 87 | background: rgba(99, 99, 99, 0.5); 88 | width: 4px; 89 | min-height: 22px; 90 | margin-top: 11px; 91 | display: none; 92 | top: -2000em; 93 | left: -2000em; 94 | } 95 | 96 | .ql-editor { 97 | font-size: 15px; 98 | line-height: 1.5; 99 | } 100 | 101 | .form-description { 102 | margin-top: 2em; 103 | } 104 | 105 | .preview-mode { 106 | text-align: right; 107 | } 108 | 109 | .preview-mode label { 110 | display: inline-block!important; 111 | padding: 0 0.5em; 112 | } 113 | 114 | .preview-full { 115 | display: none; 116 | } -------------------------------------------------------------------------------- /theme/furion/description.md: -------------------------------------------------------------------------------- 1 | ## Furion 2 | 3 | > ( 아직사용할수없습니다 ) 팀 유저 블로그 시스템 4 | 5 | Pure CSS Framework 를 사용한 블로그 테마 6 | 7 | ### History 8 | 9 | - 1.0.0: initial release 10 | 11 | ### Credit 12 | 13 | - soomtong (github.com/soomtong) -------------------------------------------------------------------------------- /theme/furion/page/_404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include '../_include/head.html' %} 5 | 6 | 7 |
8 | 9 | {% include '../_include/menu.html' %} 10 | 11 |
12 |
13 | 14 |
15 |

Can't resolve this request

16 | 17 | 18 |
19 |
20 | 21 | 22 |

404!

23 | 24 |
25 | 26 |
27 |

28 | there is no way to find this address: {{ url }} 29 |

30 |
31 |
32 |
33 | 34 | {% include '../_include/footer.html' %} 35 |
36 |
37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /theme/furion/page/_500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include '../_include/head.html' %} 5 | 6 | 7 |
8 | 9 | {% include '../_include/menu.html' %} 10 | 11 |
12 |
13 | 14 |
15 |

Can't resolve this request

16 | 17 | 18 |
19 |
20 | 21 | 22 |

500!

23 | 24 |
25 | 26 |
27 |

28 | there is some problems: {{ error }} 29 |

30 |
31 |
32 |
33 | 34 | {% include '../_include/footer.html' %} 35 |
36 |
37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /theme/furion/page/_include/headed_picture.html: -------------------------------------------------------------------------------- 1 | {% macro pinned(item) %} 2 |
3 |
4 | {% for img in item.images %} 5 |
6 | {{img.title}} 7 | 8 |
9 |

{{img.title}}

10 |
11 |
12 | {% endfor %} 13 |
14 |
15 | {% endmacro %} 16 | {% macro recent(item) %} 17 |
18 |
19 | {% for img in item.images %} 20 |
21 | {{img.title}} 22 | 23 |
24 |

{{img.title}}

25 |
26 |
27 | {% endfor %} 28 |
29 |
30 | {% endmacro %} -------------------------------------------------------------------------------- /theme/furion/page/_private.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/furion/page/_private.html -------------------------------------------------------------------------------- /theme/furion/page/account/sign_in.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include '../../include/head.html' %} 5 | 6 | 7 |
8 | 9 | {% include '../../include/menu.html' %} 10 | 11 |
12 |
13 |
14 | 15 |

Sign In

16 | 17 |
18 | 44 | 45 | 46 | 47 | 48 |
49 |
50 | 51 |
52 | 55 |
56 | 57 | {% include '../../include/footer.html' %} 58 |
59 |
60 |
61 | 62 | 63 | -------------------------------------------------------------------------------- /theme/furion/page/account/sign_up.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include '../../include/head.html' %} 5 | 6 | 7 |
8 | 9 | {% include '../../include/menu.html' %} 10 | 11 |
12 |
13 |
14 | 15 |

Sign Up

16 | 17 |
18 | 42 | 43 | {% if message.error %} 44 | {% for error in message.error %} 45 | 48 | {% endfor %} 49 | {% endif %} 50 | 51 | 52 | 53 |
54 | 55 |
56 | 57 |
58 | 61 |
62 | 63 | 64 | {% include '../../include/footer.html' %} 65 |
66 |
67 |
68 | 69 | 70 | -------------------------------------------------------------------------------- /theme/furion/page/teamblog/view.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include '../../include/head.html' %} 5 | 6 | 7 | 8 | 9 |
10 | 11 | {% include '../../include/menu.html' %} 12 | 13 |
14 |
15 | 16 |
17 |

post view count, feedback count, social sharing action

18 | 19 | {% set cls = cycler("1", "2", "3", "4") %} 20 | 21 |
22 |
23 | {{post.nickname}} 24 | 25 |

{{post.title}}

26 | 27 | 38 |
39 | 40 |
41 | {% if post.renderMarkdown %} 42 |
43 | {{post.rendered | safe }} 44 |
45 | {% elif post.renderDelta %} 46 |
47 | {{post.rendered | safe }} 48 |
49 | {% else %} 50 |
51 | {{post.content | safe}} 52 |
53 | {% endif %} 54 |
55 | 56 |
57 | 58 |
59 | 60 |
61 |
62 | related post or something 63 |
64 |
65 | 66 | {% include '../../include/footer.html' %} 67 |
68 |
69 |
70 | 71 | 72 | -------------------------------------------------------------------------------- /theme/furion/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/furion/screenshot.jpg -------------------------------------------------------------------------------- /theme/plain/_include/footer.html: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /theme/plain/_include/header.html: -------------------------------------------------------------------------------- 1 | {% import './header_item.html' as Header %} 2 |
3 |
4 | {{app.title}} 5 |
    6 | {% for item in siteMenu %} 7 | {% if not user %} 8 | {% if item.logged < 0 %} 9 | {{ Header.item(item, site) }} 10 | {% endif%} 11 | {% else %} 12 | {% if item.id != "login" %} 13 | {{ Header.item(item, site) }} 14 | {% endif %} 15 | {% endif %} 16 | {% endfor %} 17 | {% if user %} 18 |
  • 로그아웃
  • 19 | {% endif %} 20 |
21 |
22 |
-------------------------------------------------------------------------------- /theme/plain/_include/header_item.html: -------------------------------------------------------------------------------- 1 | {% macro item(item, site) %} 2 | {% if item.id == page_id %} 3 |
  • {{item.name}}
  • 4 | {% else %} 5 |
  • {{item.name}}
  • 6 | {% endif %} 7 | {% endmacro %} -------------------------------------------------------------------------------- /theme/plain/_include/style.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /theme/plain/_include/sub_section.html: -------------------------------------------------------------------------------- 1 |
    2 | File Icons 3 |
    4 |
    5 | 6 |

    B L I T I T O R

    7 | 8 |

    9 | 플래인 테마를 사용하고 있는 블리티터 입니다.
    10 | 블리티터의 채팅 모듈을 중심으로 꾸며진 예제로 계정 등록, 로그인/아웃, 채팅 관리 등의 기능을 제공하고 있습니다. 11 |

    12 |
    -------------------------------------------------------------------------------- /theme/plain/admin/_include/check.html: -------------------------------------------------------------------------------- 1 | {% macro check(grant) %} 2 | {% if grant %} checked {% endif %} 3 | {% endmacro %} -------------------------------------------------------------------------------- /theme/plain/admin/_include/header.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | {{site.title}} 4 | 5 |
      6 | {% if user %} 7 | {% for item in adminMenu %} 8 | {% if item.url == site.url %} 9 |
    • {{item.name}}
    • 10 | {% else %} 11 |
    • {{item.name}}
    • 12 | {% endif %} 13 | {% endfor %} 14 |
    • 로그아웃
    • 15 | {% endif %} 16 |
    17 |
    18 |
    -------------------------------------------------------------------------------- /theme/plain/admin/_include/style.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /theme/plain/admin/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{app.title}} - {{site.title}} 6 | {% include './_include/style.html' %} 7 | 8 | 9 | 10 | {% include '../_include/header.html' %} 11 | 12 |
    13 |
    14 |
    15 |
    16 |

    ACCESS ADMIN ONLY

    17 |

    시스템 관리자는 사이트에 등록된 모든 계정을 관리합니다.

    18 |
      19 |
    • 신규 계정 등록/삭제
    • 20 |
    • 계정 권한 조정
    • 21 |
    22 | 23 |
    24 |
    25 | Admin Login 26 | 27 |
    28 |
    29 | 30 | 31 |
    32 | 33 |
    34 | 35 | 36 |
    37 | 38 |
    39 | 40 | 43 | 44 | {% if message.error %} 45 | {% for error in message.error %} 46 | 49 | {% endfor %} 50 | {% endif %} 51 | 52 | 53 | 54 |
    55 |
    56 | 57 |
    58 |
    59 |
    60 | 61 |
    62 |
    63 | File Icons 64 |
    65 |
    66 | 67 |

    B L I T I T O R

    68 | 69 |

    70 | 플래인 테마를 사용하고 있는 블리티터 입니다.
    71 | 블리티터의 팀블로그 모듈을 중심으로 꾸며진 예제로 회원관리, 블로그 포스트 관리, 방명록 관리 등의 기능을 제공하고 있습니다. 72 |

    73 |
    74 |
    75 | 76 | {% include '../_include/footer.html' %} 77 | 78 |
    79 | 80 | -------------------------------------------------------------------------------- /theme/plain/admin/sign_up.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{app.title}} - {{site.title}} 6 | {% include './_include/style.html' %} 7 | 8 | 9 | 10 | {% include './_include/header.html' %} 11 | 12 |
    13 |
    14 |
    15 |
    16 |

    시스템 관리자는 사이트에 등록된 모든 계정을 관리합니다.

    17 |
      18 |
    • 신규 계정 등록/삭제
    • 19 |
    • 계정 권한 조정
    • 20 |
    21 |
    22 |
    23 |
    24 | 25 |
    26 |
    27 |
    28 | 54 |
    55 |
    56 |
    57 | 58 | {% include '../_include/footer.html' %} 59 | 60 |
    61 | 62 | -------------------------------------------------------------------------------- /theme/plain/common/asset/blititor_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/plain/common/asset/blititor_logo.png -------------------------------------------------------------------------------- /theme/plain/common/asset/blititor_new_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/plain/common/asset/blititor_new_logo.png -------------------------------------------------------------------------------- /theme/plain/common/asset/blititor_new_logo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/plain/common/asset/blititor_new_logo_white.png -------------------------------------------------------------------------------- /theme/plain/common/asset/cd-icon-arrow-1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /theme/plain/common/asset/cd-icon-arrow-2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /theme/plain/common/asset/photo-user1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/plain/common/asset/photo-user1.png -------------------------------------------------------------------------------- /theme/plain/common/chat.js: -------------------------------------------------------------------------------- 1 | var socket = io(); 2 | 3 | $(funtion () { 4 | var $userList = $('#users'); 5 | var $publicForm = $('#public'); 6 | var $privateForm = $('#private'); 7 | var $messages = $('#messages'); 8 | 9 | $publicForm.submit(function () { 10 | var message = $('#message_pub'); 11 | 12 | socket.emit('chat message', { 13 | msg: message.val() 14 | }); 15 | 16 | message.val(''); 17 | 18 | return false; 19 | }); 20 | 21 | $privateForm.submit(function () { 22 | var nickname = $('#nickname'); 23 | var message = $('#message_pri'); 24 | 25 | socket.emit('chat message', { 26 | nickname: nickname.val(), 27 | msg: message.val() 28 | }); 29 | 30 | $messages.append($(' 5 | {% endmacro %} 6 | {% macro itemGranted(item, site) %} 7 | 10 | {% endmacro %} -------------------------------------------------------------------------------- /theme/simplestrap/page/_private.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/simplestrap/page/_private.html -------------------------------------------------------------------------------- /theme/simplestrap/page/account/sign_in.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include '../_include/header.html' %} 5 | 6 | 7 | 8 |
    9 |
    10 | 11 | {% include '../_include/menu.html' %} 12 | 13 |
    14 | 15 |
    16 |
    17 |
    18 | 19 |

    Sign In

    20 |
    21 |
    22 | 23 | 24 | We'll never share your email with anyone else. 25 |
    26 |
    27 | 28 | 29 |
    30 | 31 | {% if message.error %} 32 | {% for error in message.error %} 33 | 36 | {% endfor %} 37 | {% endif %} 38 | 39 |
    40 | 43 |
    44 | 45 | 46 | 47 |
    48 |
    49 |
    50 |
    51 | 52 |
    53 | 54 |
    55 |
    56 |

    Subheading

    57 |

    Donec id elit non mi porta gravida at eget metus. Maecenas faucibus mollis interdum.

    58 | 59 |
    Blog heroes
    60 |

    Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Cras mattis consectetur purus sit amet fermentum.

    61 | 62 |
      63 |
    • Maecenas sed diam eget risus varius blandit sit amet non magna.
    • 64 |
    • Maecenas sed diam eget risus varius blandit sit amet non magna.
    • 65 |
    • Maecenas sed diam eget risus varius blandit sit amet non magna.
    • 66 |
    67 |
    68 |
    69 | 70 | {% include '../_include/footer.html' %} 71 | 72 |
    73 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /theme/simplestrap/page/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include './_include/header.html' %} 5 | 6 | 7 | 8 |
    9 |
    10 | 11 | {% include './_include/menu.html' %} 12 | 13 |
    14 | 15 | {% include './_include/flash.html' %} 16 | 17 |
    18 |

    안녕하세요!

    19 |

    블리티터는 Node.js, MySQL 기반의 설치형 웹 사이트 템플릿입니다.
    다양한 디자인의 템플릿을 제공하고 있으며 능력이 되는대로 쉽게 고쳐 쓸 수 있으며, 단순한 블로그부터 복잡한 커뮤니티 사이트까지 사용할 수 있도록 개발되고 있습니다.

    20 |

    21 | {% if user.uuid %} 개인정보 수정 22 | {% else %} 팀 블로거로 가입하기 23 | {% endif%} 24 |

    25 |
    26 | 27 |
    28 | {% for item in recentPostList %} 29 |
    30 |

    {{ item.title }}

    31 |

    {{ item.preview }}

    32 |
    33 | {% endfor %} 34 |
    35 | 36 | {% include './_include/footer.html' %} 37 | 38 |
    39 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /theme/simplestrap/page/teamblog/write.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {% include '../_include/header.html' %} 5 | 6 | 7 | 8 |
    9 |
    10 | 11 | {% include '../_include/menu.html' %} 12 | 13 |
    14 | 15 |
    16 |
    17 |
    18 | 19 |

    Team Blog

    20 |
    21 |
    22 | 23 | 24 |
    25 |
    26 | 27 | 28 |
    29 | 30 | {% if message.error %} 31 | {% for error in message.error %} 32 | 35 | {% endfor %} 36 | {% endif %} 37 | 38 | 39 | 40 |
    41 | 42 |
    43 |
    44 |
    45 | 46 |
    47 | 48 | {% include '../_include/footer.html' %} 49 | 50 |
    51 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 67 | -------------------------------------------------------------------------------- /theme/simplestrap/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/simplestrap/screenshot.jpg -------------------------------------------------------------------------------- /theme/simplestrap/screenshot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/simplestrap/screenshot2.jpg -------------------------------------------------------------------------------- /theme/simplestrap/screenshot3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/soomtong/blititor/4c0e0d0366c36a48ecef4702993a2e22623c9eda/theme/simplestrap/screenshot3.jpg -------------------------------------------------------------------------------- /theme/simplestrap/setup/_include/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/simplestrap/setup/_include/header.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /theme/simplestrap/setup/_partial/setup-database-done.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 5 |
    6 |

    성공! 데이터베이스 인증 완료.

    7 |
    8 | 9 |
    10 |

    데이터베이스 인증을 마쳤습니다.

    11 |

    인증된 데이터베이스에 블리티터 초기를 진행합니다.

    12 | 다음으로 이동! 13 |
    14 | 15 |
    16 |
    17 |
    -------------------------------------------------------------------------------- /theme/simplestrap/setup/_partial/setup-database-error.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 5 |
    6 |

    실패! 데이터베이스 인증 실패.

    7 |
    8 | 9 |
    10 |

    데이터베이스 서버 정보와 아이디와 패스워드를 확인해주세요.

    11 |

    데이터베이스 인증이 진행되지 않으면 다음단계로 진행할 수 없습니다.

    12 | 다시! 13 |
    14 | 15 |
    16 |
    17 |
    -------------------------------------------------------------------------------- /theme/simplestrap/setup/_partial/setup-database-table-done.html: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | 5 |
    6 |

    성공! 데이터베이스 테이블 생성 완료.

    7 |
    8 | 9 |
    10 |

    데이터베이스 테이블 생성을 마쳤습니다.

    11 |

    준비된 블리티터 테마를 선택​합니다.

    12 | 다음으로 이동! 13 |
    14 | 15 |
    16 |
    17 |
    -------------------------------------------------------------------------------- /theme/simplestrap/setup/setup-database-table.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{site.title}} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | {% include site.theme + '/' + site.themeType.setup + '/include/header.html' %} 18 | 19 |
    20 |
    21 | 22 |

    Database Initialize

    23 |

    24 | 데이터베이스를 만들고 테이블을 초기화합니다 25 |

    26 |
    27 |
    28 |
    29 |
    30 |
    31 | 32 |
    33 |
    34 | 35 | 36 | 기본적으로 지정된 데이터베이스 이름은 위와 같습니다. 다른 이름을 사용할 경우 변경해주세요. 37 |
    38 | 44 | 45 | 46 | 47 |
    48 | 49 |
    50 |
    51 |
    52 | 53 | {% include site.theme + '/' + site.themeType.setup + '/include/footer.html' %} 54 | 55 | 56 | 57 | 58 | 59 | 60 | 77 | 78 | -------------------------------------------------------------------------------- /theme/simplestrap/setup/setup.css: -------------------------------------------------------------------------------- 1 | /* setup */ 2 | 3 | .card-deck { 4 | margin: 2rem 0; 5 | } 6 | 7 | .card { 8 | margin-bottom: 1.5rem; 9 | } 10 | 11 | .bd-pageheader .container { 12 | position: relative 13 | } 14 | 15 | .bd-pageheader { 16 | padding: 2rem .9375rem; 17 | margin-bottom: 1.5rem; 18 | color: #d8e5eb; 19 | text-align: center; 20 | background-color: #46677c 21 | } 22 | 23 | .bd-pageheader h1 { 24 | font-size: 3rem; 25 | font-weight: 400; 26 | color: #fff 27 | } 28 | 29 | .bd-pageheader p { 30 | margin-bottom: 0; 31 | font-size: 1.25rem; 32 | font-weight: 300 33 | } 34 | 35 | @media (min-width: 34em) { 36 | .bd-pageheader { 37 | padding-top: 4rem; 38 | padding-bottom: 4rem; 39 | margin-bottom: 3rem; 40 | text-align: left 41 | } 42 | } 43 | 44 | @media (min-width: 62em) { 45 | .bd-pageheader h1, .bd-pageheader p { 46 | margin-right: 380px 47 | } 48 | } 49 | 50 | @media (min-width: 48em) { 51 | .bd-pageheader h1 { 52 | font-size: 4rem 53 | } 54 | 55 | .bd-pageheader p { 56 | font-size: 1.5rem 57 | } 58 | } 59 | 60 | .bd-footer { 61 | padding: 4rem 0; 62 | margin-top: 4rem; 63 | font-size: 85%; 64 | background-color: #f7f7f7; 65 | text-align: center 66 | } 67 | 68 | .bd-footer a { 69 | font-weight: 500; 70 | color: #55595c 71 | } 72 | 73 | .bd-footer a:hover { 74 | color: #0275d8 75 | } 76 | 77 | .bd-footer p { 78 | margin-bottom: 0 79 | } 80 | 81 | .bd-footer-links { 82 | margin-bottom: 1rem 83 | } 84 | 85 | @media (min-width: 34em) { 86 | .bd-footer { 87 | text-align: left 88 | } 89 | } 90 | 91 | .bd-footer-links { 92 | padding-left: 0 93 | } 94 | 95 | .bd-footer-links li { 96 | display: inline-block 97 | } 98 | 99 | .bd-footer-links li + li { 100 | margin-left: 1rem 101 | } 102 | -------------------------------------------------------------------------------- /theme/status404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{app.title}} - {{site.title}} 6 | 21 | 22 | 23 |
    24 |
    25 |

    A page isn't exist

    26 | 27 | {{ url }} 28 | 29 |
    30 | 31 |
    32 | 33 | -------------------------------------------------------------------------------- /theme/status500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{app.title}} - {{site.title}} 6 | 21 | 22 | 23 |
    24 |
    25 |

    An error was encountered

    26 | 27 | {{error}} 28 | 29 |
    30 | 31 |
    32 | 33 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | - [ ] remove bower 2 | - [ ] introduce cli 3 | --------------------------------------------------------------------------------