├── .gitignore ├── static ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.ttf │ ├── glyphicons-halflings-regular.woff │ └── glyphicons-halflings-regular.woff2 ├── js │ ├── npm.js │ ├── bootstrapSwitch.js │ └── bootstrap.min.js └── css │ ├── bootstrapSwitch.css │ ├── bootstrap-theme.min.css │ ├── bootstrap-theme.css │ └── bootstrap-theme.css.map ├── index.py ├── clean.sh ├── sample.cfg ├── singleton.py ├── login.py ├── README.md ├── log.py ├── config.py ├── server.py ├── header.sh └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | server.cfg 3 | -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdtianyu/SmallTalkService/master/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdtianyu/SmallTalkService/master/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdtianyu/SmallTalkService/master/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xdtianyu/SmallTalkService/master/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /index.py: -------------------------------------------------------------------------------- 1 | ''' 2 | File name: index.py 3 | Author: xdtianyu@gmail.com 4 | Date created: 2015-01-25 09:54:16 5 | Date last modified: 2015-03-15 12:41:23 6 | Python Version: 2.7.3 7 | ''' 8 | 9 | 10 | def show_index(): 11 | return ''' 12 |

Welcome to SmallTalk service.

13 | Login 14 | ''' 15 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $(find -name \*.pyc|wc -l) != 0 ];then 4 | rm *.pyc 5 | fi 6 | 7 | if [ -f ".auto" ];then 8 | rm .auto 9 | fi 10 | 11 | if [ -d "dist" ];then 12 | rm -r dist 13 | fi 14 | 15 | if [ -d "build" ];then 16 | rm -r build 17 | fi 18 | 19 | if [ -f "server.spec" ];then 20 | rm server.spec 21 | fi 22 | 23 | echo "DONE!" 24 | 25 | -------------------------------------------------------------------------------- /sample.cfg: -------------------------------------------------------------------------------- 1 | # SmallTalkService config file, author xdtianyu@gmail.com 2 | 3 | [server] 4 | host = 0.0.0.0 5 | port = 50000 6 | 7 | [xmpp] 8 | xmpp_server = 127.0.01 9 | xmpp_user = 10000 10 | xmpp_password = 123456 11 | 12 | [mysql] 13 | mysql_host = localhost 14 | mysql_database = smalltalk 15 | mysql_user = root 16 | mysql_pass = 123456 17 | 18 | [extra] 19 | debug = true 20 | log_color = true 21 | -------------------------------------------------------------------------------- /singleton.py: -------------------------------------------------------------------------------- 1 | ''' 2 | File name: singleton.py 3 | Author: xdtianyu@gmail.com 4 | Date created: 2015-03-15 12:34:57 5 | Date last modified: 2015-03-15 12:41:23 6 | Python Version: 2.7.6 7 | ''' 8 | 9 | def singleton(class_): 10 | instances = {} 11 | def getinstance(*args, **kwargs): 12 | if class_ not in instances: 13 | instances[class_] = class_(*args, **kwargs) 14 | return instances[class_] 15 | return getinstance 16 | -------------------------------------------------------------------------------- /static/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /login.py: -------------------------------------------------------------------------------- 1 | ''' 2 | File name: login.py 3 | Author: xdtianyu@gmail.com 4 | Date created: 2015-02-18 20:20:59 5 | Date last modified: 2015-03-15 12:41:23 6 | Python Version: 2.7.6 7 | ''' 8 | 9 | from flask import jsonify 10 | 11 | def post(request, mysql): 12 | username = request.form['username'] 13 | password = request.form['password'] 14 | cursor = mysql.connect().cursor() 15 | cursor.execute("SELECT * from user where username='"+ username + "' and password= '" + password + "'") 16 | data = cursor.fetchone() 17 | if data is None: 18 | return jsonify(result="failed", message="Username or Password is wrong") 19 | else: 20 | return jsonify(result="succeed", message="Logged in successfully") 21 | 22 | def show_login(): 23 | return "login"; 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SmallTalkService 2 | SmallTalkService is a web interface for SmallTalk, it's still under development. 3 | 4 | ###Develop Dependence 5 | 6 | ```bash 7 | apt-get install libav-tools git 8 | pip install Flask 9 | pip install pytz 10 | pip install pyinstaller 11 | pip install ansi2html 12 | pip install sleekxmpp 13 | pip install dnspython 14 | ``` 15 | 16 | ###How to make a release 17 | 18 | In short, just run ./build.sh. 19 | 20 | Detail: 21 | 22 | ```bash 23 | python server.py -g 24 | pyinstaller server.py -F 25 | ``` 26 | This will generate a file named 'server' in dist directory. Copy file/directory server.cfg, .auto, records, statics to dist and run the follow command. 27 | 28 | ```bash 29 | sudo -s 30 | ./server 31 | ``` 32 | 33 | Then test if everything is OK, server should run on any linux distributions. 34 | 35 | 36 | ###Author 37 | xdtianyu@gmail.com 38 | 39 | -------------------------------------------------------------------------------- /log.py: -------------------------------------------------------------------------------- 1 | ''' 2 | File name: log.py 3 | Author: xdtianyu@gmail.com 4 | Date created: 2015-03-15 13:02:20 5 | Date last modified: 2015-03-15 13:04:20 6 | Python Version: 2.7.6 7 | ''' 8 | 9 | from time import localtime, strftime 10 | 11 | from singleton import singleton 12 | from config import config 13 | 14 | @singleton 15 | class Logger: 16 | 17 | def _log(self, s, color): 18 | time = strftime("%d/%b/%Y %H:%M:%S", localtime()) 19 | if config.log_color: 20 | print("{}{} - - [{}] \"{}\"{}".format(color, config.host, time, s, bcolors.ENDC)) 21 | else: 22 | print("{} - - [{}] \"{}\"".format(config.host, time, s)) 23 | 24 | def log(self, s): 25 | self._log(s, bcolors.OKGREEN) 26 | 27 | def debug(self, s): 28 | self._log(s, bcolors.OKBLUE) 29 | 30 | def error(self, s): 31 | self._log(s, bcolors.FAIL) 32 | 33 | def info(self, s): 34 | if config.log_color: 35 | print("{} * {}{}".format(bcolors.WARNING, s, bcolors.ENDC)) 36 | else: 37 | print(" * {}".format(s)) 38 | 39 | class bcolors: 40 | HEADER = '\033[95m' 41 | OKBLUE = '\033[94m' 42 | OKGREEN = '\033[92m' 43 | WARNING = '\033[93m' 44 | FAIL = '\033[91m' 45 | ENDC = '\033[0m' 46 | BOLD = '\033[1m' 47 | UNDERLINE = '\033[4m' 48 | 49 | logger = Logger() 50 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | ''' 2 | File name: config.py 3 | Author: xdtianyu@gmail.com 4 | Date created: 2015-03-15 12:35:32 5 | Date last modified: 2015-03-15 13:04:20 6 | Python Version: 2.7.6 7 | ''' 8 | import os 9 | from singleton import singleton 10 | import ConfigParser 11 | 12 | @singleton 13 | class Config(): 14 | bin_path = './' 15 | 16 | host = '127.0.0.1' 17 | port = 8080 18 | 19 | xmpp_server = '127.0.0.1' 20 | xmpp_user = '' 21 | xmpp_password = '' 22 | 23 | mysql_host = '' 24 | mysql_database = '' 25 | mysql_user = '' 26 | mysql_pass = '' 27 | 28 | debug = False 29 | log_color = False 30 | 31 | 32 | def load(self, config): 33 | if not os.path.isfile(config): 34 | print " * Error parsing config: FILE NOT EXIST. Using default config." 35 | else: 36 | conf = ConfigParser.ConfigParser() 37 | conf.read(config) 38 | 39 | self.host = conf.get('server', 'host') 40 | self.port = conf.getint('server', 'port') 41 | 42 | self.xmpp_server = conf.get('xmpp', 'xmpp_server') 43 | self.xmpp_user = conf.get('xmpp', 'xmpp_user') 44 | self.xmpp_password = conf.get('xmpp', 'xmpp_password') 45 | 46 | self.mysql_host = conf.get('mysql', 'mysql_host') 47 | self.mysql_database = conf.get('mysql', 'mysql_database') 48 | self.mysql_user = conf.get('mysql', 'mysql_user') 49 | self.mysql_pass = conf.get('mysql', 'mysql_pass') 50 | 51 | self.debug = conf.getboolean('extra', 'debug') 52 | self.log_color = conf.getboolean('extra', 'log_color') 53 | 54 | config = Config(); 55 | -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- 1 | ''' 2 | File name: server.py 3 | Author: xdtianyu@gmail.com 4 | Date created: 2015-01-25 09:56:23 5 | Date last modified: 2015-03-15 13:07:50 6 | Python Version: 2.7.3 7 | ''' 8 | 9 | from flask import Flask 10 | from flask import request 11 | from flaskext.mysql import MySQL 12 | 13 | from config import config 14 | 15 | import os.path 16 | import sys 17 | import getopt 18 | 19 | 20 | import index 21 | import login 22 | 23 | mysql = MySQL() 24 | app = Flask(__name__, static_url_path="/static") 25 | 26 | 27 | @app.route("/") 28 | def root(): 29 | return index.show_index() 30 | 31 | @app.route("/login", methods=["GET","POST"]) 32 | def show_control(): 33 | if request.method == "POST": 34 | return login.post(request, mysql) 35 | else: 36 | return login.show_login() 37 | 38 | if __name__ == '__main__': 39 | config.bin_path = os.path.realpath(os.path.dirname(sys.argv[0])) 40 | config_file = config.bin_path+'/server.cfg' 41 | try: 42 | opts, args = getopt.getopt(sys.argv[1:], "hc:g", ["help", "config=", "generate"]) 43 | except getopt.GetoptError: 44 | print ' Usage: server.py -c ' 45 | sys.exit(2) 46 | for opt, arg in opts: 47 | if opt in ('-h', "--help"): 48 | print ' Usage: server.py -c ' 49 | sys.exit() 50 | elif opt in ("-c", "--config"): 51 | config_file = arg 52 | elif opt in ("-g", "--generate"): 53 | config.load(config_file) 54 | #about.version() 55 | sys.exit() 56 | 57 | config.load(config_file) 58 | 59 | 60 | app.config['MYSQL_DATABASE_USER'] = config.mysql_user 61 | app.config['MYSQL_DATABASE_PASSWORD'] = config.mysql_pass 62 | app.config['MYSQL_DATABASE_DB'] = config.mysql_database 63 | app.config['MYSQL_DATABASE_HOST'] = config.mysql_host 64 | mysql.init_app(app) 65 | 66 | app.run(debug=config.debug, host=config.host, port=config.port) 67 | -------------------------------------------------------------------------------- /header.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #''' 3 | # File name: header.sh 4 | # Author: xdtianyu@gmail.com 5 | # Date created: 2015-01-07 14:24:16 6 | # Date last modified: 2015-01-09 15:19:31 7 | # Bash Version: 4.3.11(1)-release 8 | #''' 9 | 10 | AUTHOR="xdtianyu@gmail.com" 11 | PYTHON_VERSION=$(python -c 'import sys; print(sys.version[:5])') 12 | 13 | for file in $(ls *.py); do 14 | echo "check $file ..." 15 | MODIFIED=$(stat -c %y $file| cut -d'.' -f1) 16 | #echo "Last modified: $MODIFIED" 17 | CURRENT_DATE=$(date "+%Y-%m-%d %H:%M:%S") 18 | AUTHOR_COUNT=$(cat "$file" |grep " Author:" |wc -l) 19 | if [ $AUTHOR_COUNT -gt 1 ];then 20 | echo "More than one author, skip." 21 | continue 22 | elif [ $AUTHOR_COUNT -eq 1 ];then 23 | echo "Have author, check modified date." 24 | ORI=$(cat $file |grep " Date last modified: ") 25 | if [ "$ORI" == "" ];then 26 | echo "no line" 27 | continue 28 | fi 29 | TARGET=" Date last modified: ${MODIFIED}" 30 | #echo $ORI 31 | #echo $TARGET 32 | if [ "$ORI" == "$TARGET" ];then 33 | echo "No change detected." 34 | else 35 | if [ $(cat $file |grep " Date last modified: "|wc -l) -gt 1 ];then 36 | echo "More than one \"Date last modified\" detected, skip" 37 | continue 38 | fi 39 | LINE=$(cat $file |grep " Date last modified: " -n | cut -d':' -f1) 40 | sed -i "${LINE}s/.*/ Date last modified: ${CURRENT_DATE}/" $file 41 | fi 42 | # Check file name 43 | FILE_COUNT=$(cat $file |grep " File name:"|wc -l) 44 | if [ $FILE_COUNT -gt 1 ];then 45 | echo "More than one \"File name\" detecetd, skip" 46 | continue 47 | elif [ $FILE_COUNT -eq 1 ];then 48 | echo "Check file name..." 49 | ORI_FILE_NAME=$(cat $file |grep " File name:") 50 | TARGET_FILE_NAME=" File name: $file" 51 | if [ ! "$ORI_FILE_NAME" == "$TARGET_FILE_NAME" ];then 52 | echo "File name changed, update now" 53 | FILE_LINE=$(cat $file |grep " File name: " -n | cut -d':' -f1) 54 | sed -i "${FILE_LINE}s/.*/${TARGET_FILE_NAME}/" $file 55 | else 56 | echo "No change detected." 57 | fi 58 | fi 59 | else 60 | echo "Have no author, add header." 61 | sed -i "1s/^/\'\'\'\n File name: $file\n Author: $AUTHOR\n Date created: $MODIFIED\n Date last modified: $CURRENT_DATE\n Python Version: $PYTHON_VERSION\n\'\'\'\n\n/" $file 62 | fi 63 | done 64 | -------------------------------------------------------------------------------- /static/js/bootstrapSwitch.js: -------------------------------------------------------------------------------- 1 | /* ============================================================ 2 | * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru 3 | * http://www.larentis.eu/switch/ 4 | * ============================================================ 5 | * Licensed under the Apache License, Version 2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * ============================================================ */ 8 | 9 | !function ($) { 10 | "use strict"; 11 | 12 | $.fn['bootstrapSwitch'] = function (method) { 13 | var methods = { 14 | init: function () { 15 | return this.each(function () { 16 | var $element = $(this) 17 | , $div 18 | , $switchLeft 19 | , $switchRight 20 | , $label 21 | , myClasses = "" 22 | , classes = $element.attr('class') 23 | , color 24 | , moving 25 | , onLabel = "ON" 26 | , offLabel = "OFF" 27 | , icon = false; 28 | 29 | $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) { 30 | if (classes.indexOf(el) >= 0) 31 | myClasses = el; 32 | }); 33 | 34 | $element.addClass('has-switch'); 35 | 36 | if ($element.data('on') !== undefined) 37 | color = "switch-" + $element.data('on'); 38 | 39 | if ($element.data('on-label') !== undefined) 40 | onLabel = $element.data('on-label'); 41 | 42 | if ($element.data('off-label') !== undefined) 43 | offLabel = $element.data('off-label'); 44 | 45 | if ($element.data('icon') !== undefined) 46 | icon = $element.data('icon'); 47 | 48 | $switchLeft = $('') 49 | .addClass("switch-left") 50 | .addClass(myClasses) 51 | .addClass(color) 52 | .html(onLabel); 53 | 54 | color = ''; 55 | if ($element.data('off') !== undefined) 56 | color = "switch-" + $element.data('off'); 57 | 58 | $switchRight = $('') 59 | .addClass("switch-right") 60 | .addClass(myClasses) 61 | .addClass(color) 62 | .html(offLabel); 63 | 64 | $label = $('