├── .gitignore
├── app.wsgi
├── page
├── index.html
├── js
│ ├── checklogin.js
│ ├── checknotlogin.js
│ ├── login.js
│ ├── reg.js
│ ├── common.js
│ ├── setting.js
│ ├── project.js
│ ├── history.js
│ ├── rsrc.js
│ ├── message.js
│ ├── util.js
│ ├── mining.js
│ └── result.js
├── img
│ ├── bg.png
│ └── loading.gif
├── logout.html
├── css
│ └── main.css
├── login.html
├── reg.html
├── message.html
├── rsrc.html
├── project.html
├── history.html
├── setting.html
├── result.html
└── mining.html
├── doc
├── img
│ ├── db.png
│ ├── knn.png
│ ├── pages.png
│ ├── apriori.jpg
│ ├── dm-page.png
│ ├── graham.png
│ ├── kmeans.png
│ ├── assoc-csv.png
│ ├── assoc-dist.png
│ ├── dm-process.png
│ ├── dm-top-10.png
│ ├── dv-process.png
│ ├── getCookie.png
│ ├── gramham-eg.gif
│ ├── kmedoids.png
│ ├── orm-static.png
│ ├── other-csv.png
│ ├── other-dist.png
│ ├── pages-arch.png
│ ├── rmp-model.png
│ ├── rsrc-page.png
│ ├── use-case.png
│ ├── algo-module.png
│ ├── apriori-impl.png
│ ├── assoc-total.png
│ ├── entire-arch.png
│ ├── history-page.png
│ ├── kmeoids-ompl.png
│ ├── message-page.png
│ ├── other-total.png
│ ├── project-page.png
│ ├── seperate-mvc.png
│ ├── setting-page.png
│ ├── dm-req-process.png
│ ├── rmp-comp-rsrc.png
│ ├── rmp-single-rsrc.png
│ ├── toolkit-archi.png
│ ├── traditional-mvc.png
│ ├── assoc-dist-chart.png
│ ├── assoc-result-page.png
│ ├── assoc-total-chart.png
│ ├── front-end-process.png
│ ├── login-req-process.png
│ ├── other-dist=chart.png
│ ├── other-result-page.png
│ ├── other-total-chart.png
│ ├── data-module-static.png
│ ├── entire-arch-dynamic.png
│ ├── req-handler-process.png
│ └── web-basic-module-static.png
├── test
│ ├── knn.txt
│ ├── nb.txt
│ ├── svm.txt
│ ├── kmeans.txt
│ └── kmedoids.txt
└── diag
│ ├── entire-arch-0.fem
│ └── traditional-mvc-0.fem
├── dm
├── __init__.py
├── datasets.py
├── clusterBase.py
├── k_medoids.py
├── preprocess.py
└── apriori.py
├── config.py
├── init
├── init.sql
├── init_db.py
├── init_rmp_iris.py
├── init_rmp_iris2.py
└── init_rmp_cart.py
├── update.js
├── index.py
├── rmp_simulator.py
└── req_handlers.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
--------------------------------------------------------------------------------
/app.wsgi:
--------------------------------------------------------------------------------
1 | from test import app as application
--------------------------------------------------------------------------------
/page/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/doc/img/db.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/db.png
--------------------------------------------------------------------------------
/page/js/checklogin.js:
--------------------------------------------------------------------------------
1 | if(getUser()) //已登录
2 | location.href = './index.html';
--------------------------------------------------------------------------------
/doc/img/knn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/knn.png
--------------------------------------------------------------------------------
/doc/img/pages.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/pages.png
--------------------------------------------------------------------------------
/doc/test/knn.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/test/knn.txt
--------------------------------------------------------------------------------
/doc/test/nb.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/test/nb.txt
--------------------------------------------------------------------------------
/doc/test/svm.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/test/svm.txt
--------------------------------------------------------------------------------
/page/img/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/page/img/bg.png
--------------------------------------------------------------------------------
/page/js/checknotlogin.js:
--------------------------------------------------------------------------------
1 | if(!getUser()) //已登录
2 | location.href = './login.html';
--------------------------------------------------------------------------------
/doc/img/apriori.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/apriori.jpg
--------------------------------------------------------------------------------
/doc/img/dm-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/dm-page.png
--------------------------------------------------------------------------------
/doc/img/graham.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/graham.png
--------------------------------------------------------------------------------
/doc/img/kmeans.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/kmeans.png
--------------------------------------------------------------------------------
/doc/test/kmeans.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/test/kmeans.txt
--------------------------------------------------------------------------------
/doc/img/assoc-csv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/assoc-csv.png
--------------------------------------------------------------------------------
/doc/img/assoc-dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/assoc-dist.png
--------------------------------------------------------------------------------
/doc/img/dm-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/dm-process.png
--------------------------------------------------------------------------------
/doc/img/dm-top-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/dm-top-10.png
--------------------------------------------------------------------------------
/doc/img/dv-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/dv-process.png
--------------------------------------------------------------------------------
/doc/img/getCookie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/getCookie.png
--------------------------------------------------------------------------------
/doc/img/gramham-eg.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/gramham-eg.gif
--------------------------------------------------------------------------------
/doc/img/kmedoids.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/kmedoids.png
--------------------------------------------------------------------------------
/doc/img/orm-static.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/orm-static.png
--------------------------------------------------------------------------------
/doc/img/other-csv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/other-csv.png
--------------------------------------------------------------------------------
/doc/img/other-dist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/other-dist.png
--------------------------------------------------------------------------------
/doc/img/pages-arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/pages-arch.png
--------------------------------------------------------------------------------
/doc/img/rmp-model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/rmp-model.png
--------------------------------------------------------------------------------
/doc/img/rsrc-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/rsrc-page.png
--------------------------------------------------------------------------------
/doc/img/use-case.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/use-case.png
--------------------------------------------------------------------------------
/doc/test/kmedoids.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/test/kmedoids.txt
--------------------------------------------------------------------------------
/page/img/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/page/img/loading.gif
--------------------------------------------------------------------------------
/doc/img/algo-module.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/algo-module.png
--------------------------------------------------------------------------------
/doc/img/apriori-impl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/apriori-impl.png
--------------------------------------------------------------------------------
/doc/img/assoc-total.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/assoc-total.png
--------------------------------------------------------------------------------
/doc/img/entire-arch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/entire-arch.png
--------------------------------------------------------------------------------
/doc/img/history-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/history-page.png
--------------------------------------------------------------------------------
/doc/img/kmeoids-ompl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/kmeoids-ompl.png
--------------------------------------------------------------------------------
/doc/img/message-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/message-page.png
--------------------------------------------------------------------------------
/doc/img/other-total.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/other-total.png
--------------------------------------------------------------------------------
/doc/img/project-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/project-page.png
--------------------------------------------------------------------------------
/doc/img/seperate-mvc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/seperate-mvc.png
--------------------------------------------------------------------------------
/doc/img/setting-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/setting-page.png
--------------------------------------------------------------------------------
/doc/img/dm-req-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/dm-req-process.png
--------------------------------------------------------------------------------
/doc/img/rmp-comp-rsrc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/rmp-comp-rsrc.png
--------------------------------------------------------------------------------
/doc/img/rmp-single-rsrc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/rmp-single-rsrc.png
--------------------------------------------------------------------------------
/doc/img/toolkit-archi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/toolkit-archi.png
--------------------------------------------------------------------------------
/doc/img/traditional-mvc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/traditional-mvc.png
--------------------------------------------------------------------------------
/doc/img/assoc-dist-chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/assoc-dist-chart.png
--------------------------------------------------------------------------------
/doc/img/assoc-result-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/assoc-result-page.png
--------------------------------------------------------------------------------
/doc/img/assoc-total-chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/assoc-total-chart.png
--------------------------------------------------------------------------------
/doc/img/front-end-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/front-end-process.png
--------------------------------------------------------------------------------
/doc/img/login-req-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/login-req-process.png
--------------------------------------------------------------------------------
/doc/img/other-dist=chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/other-dist=chart.png
--------------------------------------------------------------------------------
/doc/img/other-result-page.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/other-result-page.png
--------------------------------------------------------------------------------
/doc/img/other-total-chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/other-total-chart.png
--------------------------------------------------------------------------------
/doc/img/data-module-static.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/data-module-static.png
--------------------------------------------------------------------------------
/doc/img/entire-arch-dynamic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/entire-arch-dynamic.png
--------------------------------------------------------------------------------
/doc/img/req-handler-process.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/req-handler-process.png
--------------------------------------------------------------------------------
/doc/img/web-basic-module-static.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wizardforcel/bs092/HEAD/doc/img/web-basic-module-static.png
--------------------------------------------------------------------------------
/dm/__init__.py:
--------------------------------------------------------------------------------
1 | from k_medoids import kmedoids
2 | from apriori import apriori
3 | from preprocess import *
4 | from datasets import *
5 |
--------------------------------------------------------------------------------
/page/logout.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/dm/datasets.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | def loadCart():
4 | return [
5 | [ '豆奶', '莴苣' , '', ''],
6 | [ '莴苣', '尿布', '葡萄酒', '甜菜' ],
7 | [ '莴苣', '尿布', '葡萄酒', '橙汁' ],
8 | [ '莴苣', '豆奶', '尿布', '葡萄酒' ],
9 | [ '莴苣', '豆奶', '尿布', '橙汁' ]
10 | ]
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | import MySQLdb
2 | import os
3 |
4 | host = 'http://localhost:5000'
5 |
6 | db = {
7 | 'host': '127.0.0.1',
8 | 'username': 'root',
9 | 'password': '123456',
10 | 'port': 3306,
11 | 'name': 'test'
12 | }
13 |
14 | smtp = {
15 | 'server': 'smtp.qq.com',
16 | 'un': 'wizard.z@qq.com',
17 | 'authcode': 'juganzlzmlfhbdja'
18 | }
19 |
20 | rmp = 'http://202.120.40.73:28080'
21 | #rmp = 'http://localhost:5000'
22 |
23 | staticPath = 'page'
24 |
25 | def getConn():
26 | return MySQLdb.connect(host=db["host"], \
27 | user=db["username"], \
28 | passwd=db["password"], \
29 | port=db["port"], \
30 | db=db["name"], \
31 | charset="utf8")
--------------------------------------------------------------------------------
/init/init.sql:
--------------------------------------------------------------------------------
1 | create table history
2 | (
3 | id int primary key auto_increment,
4 | userid varchar(16),
5 | proj varchar(32),
6 | rsrc varchar(32),
7 | tp varchar(16),
8 | tm timestamp
9 | ) DEFAULT CHARSET=utf8
10 |
11 | create table result
12 | (
13 | hid int,
14 | id varchar(32),
15 | res1 varchar(16),
16 | res2 varchar(256),
17 | res3 varchar(16),
18 | res4 varchar(16),
19 | primary key(hid, id),
20 | foreign key(hid) references history(id)
21 | ) DEFAULT CHARSET=utf8
22 |
23 | create table message
24 | (
25 | id int primary key auto_increment,
26 | userid varchar(16),
27 | content varchar(64),
28 | tm timestamp,
29 | isread tinyint default 0
30 | ) DEFAULT CHARSET=utf8
31 |
32 | create table email
33 | (
34 | userid varchar(16) primary key,
35 | email varchar(32)
36 | )DEFAULT CHARSET=utf8
--------------------------------------------------------------------------------
/init/init_db.py:
--------------------------------------------------------------------------------
1 | from sklearn import datasets
2 | from sklearn.cluster import KMeans, MiniBatchKMeans
3 | import MySQLdb
4 | iris = datasets.load_iris()
5 | #digits = datasets.load_digits()
6 | #print type(iris.data), iris.data.shape
7 | #print iris.target
8 |
9 | """
10 | conn = MySQLdb.connect(host='127.0.0.1',user='root',passwd='123456',db="test")
11 | cur = conn.cursor()
12 |
13 | for i in range(len(iris.data)):
14 | elem = iris.data[i];
15 | sql = "insert into iris values (%s, %s, %s, %s, %s)"
16 | cur.execute(sql, (i, elem[0], elem[1], elem[2], elem[3]))
17 |
18 | conn.commit()
19 | cur.close()
20 | conn.close()
21 | """
22 |
23 | clf = KMeans(n_clusters=9)
24 | clf.fit(iris.data)
25 | print clf,"\n", clf.labels_,"\n", clf.cluster_centers_
26 |
27 | """
28 | clf = MiniBatchKMeans(n_clusters=9)
29 | clf.fit(iris.data)
30 | print clf,"\n", clf.labels_,"\n", clf.cluster_centers_
31 | """
--------------------------------------------------------------------------------
/init/init_rmp_iris.py:
--------------------------------------------------------------------------------
1 | from sklearn import datasets
2 | import urllib2
3 | import json
4 | iris = datasets.load_iris()
5 |
6 | headers = {
7 | 'Content-Type': 'application/json',
8 | 'passwd': '123456'
9 | }
10 | url = 'http://202.120.40.73:28080/Entity/U7f2d2f8faaa9/test/Iris/?userid=233837063867287'
11 |
12 |
13 | #r = []
14 | for row in iris.data:
15 | elem = {
16 | "col0": int(row[0] * 10) / 10.0,
17 | "col1": int(row[1] * 10) / 10.0,
18 | "col2": int(row[2] * 10) / 10.0,
19 | "col3": int(row[3] * 10) / 10.0
20 | }
21 | #r.append(elem)
22 | postStr = json.dumps(elem)
23 | req = urllib2.Request(url, postStr, headers)
24 | res = urllib2.urlopen(req)
25 | print res.read().decode('utf-8')
26 | #postStr = json.dumps(r)
27 |
28 | """
29 | req = urllib2.Request(url, postStr, headers)
30 | res = urllib2.urlopen(req)
31 | print res.read().decode('utf-8')
32 | """
--------------------------------------------------------------------------------
/init/init_rmp_iris2.py:
--------------------------------------------------------------------------------
1 | from sklearn import datasets
2 | import urllib2
3 | import json
4 | iris = datasets.load_iris()
5 |
6 | headers = {
7 | 'Content-Type': 'application/json',
8 | 'passwd': '123456'
9 | }
10 | url = 'http://202.120.40.73:28080/Entity/U7f2d2f8faaa9/test/Iris2/?userid=233837063867287'
11 |
12 |
13 | #r = []
14 | i = 0
15 | for row in iris.data:
16 | elem = {
17 | "col0": int(row[0] * 10) / 10.0,
18 | "col1": int(row[1] * 10) / 10.0,
19 | "col2": int(row[2] * 10) / 10.0,
20 | "col3": int(row[3] * 10) / 10.0,
21 | "label": iris.target[i]
22 | }
23 | #r.append(elem)
24 | postStr = json.dumps(elem)
25 | req = urllib2.Request(url, postStr, headers)
26 | res = urllib2.urlopen(req)
27 | print res.read().decode('utf-8')
28 | i += 1
29 | #postStr = json.dumps(r)
30 |
31 | """
32 | req = urllib2.Request(url, postStr, headers)
33 | res = urllib2.urlopen(req)
34 | print res.read().decode('utf-8')
35 | """
--------------------------------------------------------------------------------
/update.js:
--------------------------------------------------------------------------------
1 | var process = require('child_process');
2 |
3 | var getTimeStr = function() {
4 |
5 | var tm = new Date();
6 | var o = {
7 | yr: tm.getFullYear(),
8 | mon: tm.getMonth() + 1,
9 | dt: tm.getDate(),
10 | hr: tm.getHours(),
11 | min: tm.getMinutes(),
12 | sec: tm.getSeconds()
13 | };
14 | for(var i in o)
15 | {
16 | o[i] = o[i].toString();
17 | if(o[i].length < 2)
18 | o[i] = '0' + o[i];
19 | }
20 | return o.yr + '-' + o.mon + '-' + o.dt +
21 | ' ' + o.hr + ':' + o.min + ':' + o.sec;
22 | };
23 |
24 | var cmds = [
25 | 'git add -A',
26 | 'git commit -m "' + getTimeStr() + '"',
27 | 'git push',
28 | 'git push github master'
29 | ];
30 |
31 | for(var cmd of cmds) {
32 | try {
33 | console.log(cmd);
34 | console.log(process.execSync(cmd).toString());
35 | } catch(ex) {
36 | console.log(ex.toString());
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/init/init_rmp_cart.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from sklearn import datasets
4 | import urllib2
5 | import json
6 | iris = datasets.load_iris()
7 |
8 | headers = {
9 | 'Content-Type': 'application/json',
10 | 'passwd': '123456'
11 | }
12 | url = 'http://202.120.40.73:28080/Entity/U7f2d2f8faaa9/test/Cart/?userid=233837063867287'
13 |
14 |
15 | dataset = [
16 | [ '豆奶', '莴苣' , '', ''],
17 | [ '莴苣', '尿布', '葡萄酒', '甜菜' ],
18 | [ '莴苣', '尿布', '葡萄酒', '橙汁' ],
19 | [ '莴苣', '豆奶', '尿布', '葡萄酒' ],
20 | [ '莴苣', '豆奶', '尿布', '橙汁' ]
21 | ]
22 |
23 | #r = []
24 | for row in dataset:
25 | elem = {
26 | "col0": row[0],
27 | "col1": row[1],
28 | "col2": row[2],
29 | "col3": row[3]
30 | }
31 | #r.append(elem)
32 | postStr = json.dumps(elem)
33 | req = urllib2.Request(url, postStr, headers)
34 | res = urllib2.urlopen(req)
35 | print res.read().decode('utf-8')
36 | #postStr = json.dumps(r)
37 |
38 | """
39 | req = urllib2.Request(url, postStr, headers)
40 | res = urllib2.urlopen(req)
41 | print res.read().decode('utf-8')
42 | """
--------------------------------------------------------------------------------
/page/js/login.js:
--------------------------------------------------------------------------------
1 | $(function()
2 | {
3 | var doLogin = function()
4 | {
5 | var un = $('#un-txt').val();
6 | var pw = $('#pw-txt').val();
7 | if(!un || !pw)
8 | {
9 | alert('用户名和密码不能为空!');
10 | return;
11 | }
12 |
13 | var url = getUrl();
14 |
15 | $.ajax({
16 | type: "GET",
17 | url: url + "/System/User?username=" + un + "&passwd=" + pw,
18 | dataType: "json",
19 | beforeSend: function (request) {
20 | request.setRequestHeader("passwd", pw);
21 | }
22 | }).done(function (data) {
23 | if (data.error != null) {
24 | alert("登录失败!\n\nError: " + data.error.message);
25 | return;
26 | }
27 | setUser(data.id, un, pw);
28 | location.href = './index.html';
29 | }).fail(function (XMLHttpRequest, textStatus, errorThrown) {
30 | alert('登录失败!\n\n' + textStatus + ": " + errorThrown);
31 | });
32 | };
33 |
34 | $('#lgn-btn').click(doLogin);
35 | });
--------------------------------------------------------------------------------
/dm/clusterBase.py:
--------------------------------------------------------------------------------
1 | from math import sqrt
2 |
3 | def importData(FIFE = 'blogdata.txt') :
4 | blogwords = []
5 | blognames = []
6 | f = open(FIFE, 'r')
7 | words = f.readline().split()
8 | #//remove '\r\n'
9 | for line in f:
10 | blog = line[:-2].split('\t')
11 | blognames.append(blog[0])
12 | blogwords.append([int(word_c) for word_c in blog[1:]] )
13 | return blogwords,blognames
14 |
15 |
16 | def pearson_distance(vector1, vector2) :
17 | """
18 | Calculate distance between two vectors using pearson method
19 | See more : http://en.wikipedia.org/wiki/Pearson_product-moment_correlation_coefficient
20 | """
21 | sum1 = sum(vector1)
22 | sum2 = sum(vector2)
23 |
24 | sum1Sq = sum([pow(v,2) for v in vector1])
25 | sum2Sq = sum([pow(v,2) for v in vector2])
26 |
27 | pSum = sum([vector1[i] * vector2[i] for i in range(len(vector1))])
28 |
29 | num = pSum - (sum1*sum2/len(vector1))
30 | den = sqrt((sum1Sq - pow(sum1,2)/len(vector1)) * (sum2Sq - pow(sum2,2)/len(vector1)))
31 |
32 | if den == 0 : return 0.0
33 | return 1.0 - num/den
--------------------------------------------------------------------------------
/page/js/reg.js:
--------------------------------------------------------------------------------
1 | $(function()
2 | {
3 | var doReg = function()
4 | {
5 | var un = $('#un-txt').val();
6 | var pw = $('#pw-txt').val();
7 | var pw2 = $('#pw2-txt').val();
8 | if(!un || !pw)
9 | {
10 | alert('用户名和密码不能为空!');
11 | return;
12 | }
13 | if(pw != pw2)
14 | {
15 | alert('两次输入密码不一致!');
16 | return;
17 | }
18 |
19 | var url = getUrl();
20 |
21 | $.ajax({
22 | type: "POST",
23 | url: url + "/System/User",
24 | dataType: "json",
25 | contentType: "application/json",
26 | data: JSON.stringify({username: un, passwd: pw}),
27 | beforeSend: function (request) {
28 | request.setRequestHeader("passwd", pw);
29 | }
30 | }).done(function (data) {
31 | if (data.error != null) {
32 | alert("登录失败!\n\nError: " + data.error.message);
33 | return;
34 | }
35 | setUser(data.message, un, pw);
36 | location.href = './index.html';
37 | }).fail(function (XMLHttpRequest, textStatus, errorThrown) {
38 | alert('注册失败!\n\n' + textStatus + ": " + errorThrown);
39 | });
40 | };
41 |
42 | $('#reg-btn').click(doReg);
43 | });
--------------------------------------------------------------------------------
/page/js/common.js:
--------------------------------------------------------------------------------
1 | $(function()
2 | {
3 | var user = getUser();
4 |
5 | if(user)
6 | {
7 | $('.navbar-nav').append('
项目');
8 | $('.navbar-nav').append('历史');
9 | $('.navbar-nav').append('消息');
10 | $('.navbar-nav').append('设置');
11 | $('.navbar-nav').append('返回主站');
12 | $('.navbar-nav').append('退出');
13 | }
14 | else
15 | {
16 | $('.navbar-nav').append('登录');
17 | $('.navbar-nav').append('注册');
18 | }
19 |
20 |
21 | var getNotify = function() {
22 | $.ajax({
23 | type: "GET",
24 | url: "notify/" + user.id + '/',
25 | dataType: "json"
26 | }).done(function(json) {
27 | if (!json.succ)
28 | alert(json.errmsg);
29 | else {
30 | if(json.unread != 0) {
31 | $('#nav-msg .badge').remove();
32 | var $badge = $('' + json.unread + '');
33 | $('#nav-msg a').append($badge);
34 | }
35 | }
36 | }).fail(function(data) {
37 | console.log('Get notify failed!');
38 | });
39 | }
40 |
41 | if(user) {
42 | getNotify();
43 | setInterval(getNotify, 1 * 60 * 1000);
44 | }
45 | });
--------------------------------------------------------------------------------
/page/js/setting.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 |
3 | var uid = localStorage['id'];
4 |
5 | var getEmail = function() {
6 |
7 | $('#modal-loading').modal('show');
8 | $.ajax({
9 | type: "GET",
10 | url: 'email/' + uid,
11 | dataType: "json"
12 | }).done(function(json) {
13 | if (!json.succ)
14 | alert(json.errmsg);
15 | else
16 | $('#email-txt').val(json.data);
17 | $('#modal-loading').modal('hide');
18 | }).fail(function(data) {
19 | alert('Network error!');
20 | $('#modal-loading').modal('hide');
21 | });
22 |
23 | };
24 |
25 | var setEmail = function() {
26 | var $emailTxt = $('#email-txt');
27 | if(!$emailTxt[0].checkValidity())
28 | {
29 | alert('邮箱格式错误!');
30 | return;
31 | }
32 |
33 | var email = $emailTxt.val();
34 |
35 | $.ajax({
36 | type: "POST",
37 | url: 'email/' + uid + '/update/',
38 | data: 'email=' + email,
39 | contentType: "application/x-www-form-urlencoded",
40 | dataType: "json"
41 | }).done(function(json) {
42 | if (!json.succ)
43 | alert(json.errmsg);
44 | else
45 | alert('设置成功!');
46 | $('#modal-loading').modal('hide');
47 | }).fail(function(data) {
48 | alert('Network error!');
49 | $('#modal-loading').modal('hide');
50 | });
51 | };
52 | $('#email-btn').click(setEmail);
53 |
54 | getEmail();
55 | });
--------------------------------------------------------------------------------
/page/css/main.css:
--------------------------------------------------------------------------------
1 | .navbar {
2 | margin-top: 15px;
3 | }
4 |
5 | .well, .navbar {
6 | border: 1px solid rgba(0, 0, 0, 0.2);
7 | }
8 |
9 | * { font-family: "Microsoft YaHei"; }
10 |
11 | @media (min-width: 1500px) {
12 | .container {
13 | width: 1470px;
14 | }
15 | }
16 |
17 | body {
18 | background-image: url(/img/bg.png);
19 | }
20 |
21 | .col-md-1,
22 | .col-md-2,
23 | .col-md-3,
24 | .col-md-4,
25 | .col-md-5,
26 | .col-md-6
27 | {
28 | padding-top: 5px;
29 | padding-bottom: 5px;
30 | }
31 |
32 | .pag-num {
33 |
34 | }
35 |
36 | .pag-next {
37 | float: right;
38 | }
39 |
40 | .pag-prev {
41 | float: left;
42 | }
43 |
44 | #pag-bar {
45 | text-align: center;
46 | border: 1px solid #337ab7;
47 | border-radius: 4px;
48 | border-top-left-radius: 0;
49 | border-top-right-radius: 0;
50 | background-color: #337ab7;
51 | padding: 0;
52 | }
53 |
54 | #pag-bar .btn {
55 | border: 0;
56 | }
57 |
58 | .axis path,
59 | .axis line{
60 | fill: none;
61 | stroke: black;
62 | /*shape-rendering: crispEdges;*/
63 | }
64 |
65 | .axis text {
66 | font-family: sans-serif;
67 | font-size: 11px;
68 | }
69 |
70 | .form-label {
71 | height: 34px;
72 | padding: 6px 12px;
73 | margin: 0;
74 | }
75 |
76 | .msg-mark {
77 | float: right;
78 | font-size: 80%;
79 | vertical-align: middle;
80 | }
81 |
82 | .msg-tm {
83 | float: right;
84 | font-size: 80%;
85 | vertical-align: middle;
86 | margin-right: 10px;
87 | }
88 |
89 | .msg-read {
90 | background: #fff;
91 | }
92 |
93 | #nav-msg .badge {
94 | margin-left: 5px;
95 | }
96 |
97 | .footer {
98 | margin-top: 20px;
99 | padding-top: 20px;
100 | border-top: 1px solid #ccc;
101 | }
102 |
103 | .panel, .well {
104 | box-shadow: inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);
105 | }
--------------------------------------------------------------------------------
/page/login.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 |
25 |
26 |
27 |
42 |
43 |
53 |
54 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/page/reg.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
23 |
24 |
25 |
26 |
27 |
42 |
43 |
54 |
55 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/page/message.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
33 |
34 |
35 |
36 |
37 |
38 |
41 |
42 |
43 |
44 |
45 |
46 |
49 |
50 |
51 |
52 |
53 |

54 |
Loading...Please wait
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/index.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from flask import Flask, send_from_directory, redirect
4 | import req_handlers
5 | import rmp_simulator
6 | import config
7 | import os
8 |
9 | app = Flask(__name__)
10 | app.debug = True
11 |
12 | app.add_url_rule('/System/User/', view_func=rmp_simulator.login)
13 | app.add_url_rule('/System/Project/', view_func=rmp_simulator.getProj)
14 | app.add_url_rule('/System/Resource/', view_func=rmp_simulator.getRsrc)
15 | app.add_url_rule('/System/Resource/list/', view_func=rmp_simulator.getRsrcList)
16 | app.add_url_rule('/Entity///Iris/', view_func=rmp_simulator.iris)
17 | app.add_url_rule('/Entity///Cart/', view_func=rmp_simulator.cart)
18 |
19 | app.add_url_rule('/mining/////', view_func=req_handlers.mining, methods=['POST'])
20 | app.add_url_rule('/history//', view_func=req_handlers.getHistory)
21 | app.add_url_rule('/history///', view_func=req_handlers.getHistoryById)
22 | app.add_url_rule('/result//', view_func=req_handlers.getResultById)
23 | app.add_url_rule('/result//csv/', view_func=req_handlers.getResultCsv)
24 | app.add_url_rule('/message//', view_func=req_handlers.getMessageUnread)
25 | app.add_url_rule('/message//all/', view_func=req_handlers.getMessageAll)
26 | app.add_url_rule('/message//mark//', view_func=req_handlers.markMessage)
27 | app.add_url_rule('/message//mark/all/', view_func=req_handlers.markMessageAll)
28 | app.add_url_rule('/notify//', view_func=req_handlers.notify)
29 | app.add_url_rule('/email//', view_func=req_handlers.getEmail)
30 | app.add_url_rule('/email//update/', view_func=req_handlers.setEmail, methods=['POST'])
31 |
32 | @app.route('/')
33 | def staticHtml(path):
34 | return send_from_directory(config.staticPath, path)
35 |
36 | @app.route('/js/')
37 | def staticJs(path):
38 | return send_from_directory(os.path.join(config.staticPath, 'js'), path)
39 |
40 | @app.route('/css/')
41 | def staticCss(path):
42 | return send_from_directory(os.path.join(config.staticPath, 'css'), path)
43 |
44 | @app.route('/img/')
45 | def staticImg(path):
46 | return send_from_directory(os.path.join(config.staticPath, 'img'), path)
47 |
48 | @app.route('/')
49 | def redirIndex():
50 | return redirect('/index.html')
51 |
52 | if __name__ == '__main__':
53 | app.run(threaded=True)
--------------------------------------------------------------------------------
/page/js/project.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 |
3 | var user = getUser();
4 | var url = getUrl() + "/System/Project?userid=" + user.id;
5 |
6 |
7 |
8 | var getProj = function()
9 | {
10 | $('#modal-loading').modal('show');
11 |
12 | $.ajax({
13 | type: "GET",
14 | url: url,
15 | dataType: "xml",
16 | beforeSend: function (request) {
17 | request.setRequestHeader("passwd", user.pw);
18 | }
19 | }).done(function(data) {
20 | var $data = $(data);
21 | var errmsg = $data.find("error").text();
22 | if (errmsg !== "")
23 | alert(errmsg);
24 | else
25 | loadProj($data.find('project'));
26 | $('#modal-loading').modal('hide');
27 | }).fail(function(data) {
28 | alert('Network error!');
29 | $('#modal-loading').modal('hide');
30 | });
31 | };
32 |
33 | var loadProj = function($list)
34 | {
35 | tmStr = getTimeStr();
36 | $('.proj-row').remove();
37 | for(var i = 0; i < $list.length; i++)
38 | {
39 | var $elem = $list.eq(i);
40 | var name = $elem.find('name').text();
41 | var tmp = name.split("/", 2);
42 | localStorage.setItem('token', tmp[0]);
43 | name = tmp[1];
44 | var time = $elem.find('time').text() || tmStr;
45 | var status = parseInt($elem.find("privilege").text());
46 | status = statusMap[status];
47 |
48 | var $tr = $('
');
49 | var $nameTd = $('' + name + ' | ');
50 | var $timeTd = $('' + time + ' | ');
51 | var $statusTd = $('' + status + ' | ');
52 | var $opTd = $(' | ');
53 | var $viewAnchor = $('查看');
54 | $opTd.append($viewAnchor);
55 | $tr.append($nameTd);
56 | $tr.append($timeTd);
57 | $tr.append($statusTd);
58 | $tr.append($opTd);
59 | $('#proj-table').append($tr);
60 | }
61 | $('.proj-view').click(viewProj);
62 | };
63 |
64 | var viewProj = function() {
65 | event.preventDefault();
66 | var proj = $(this).parent().parent().children('.proj-name').text();
67 | localStorage.setItem('proj', proj);
68 | location.href = './rsrc.html';
69 | };
70 |
71 | getProj();
72 | });
--------------------------------------------------------------------------------
/page/rsrc.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
33 |
34 |
37 |
38 |
39 | | 名称 |
40 | 状态 |
41 | 最后修改 |
42 | 操作 |
43 |
44 |
45 |
46 |
47 |
50 |
51 |
52 |
53 |
54 |
55 |
58 |
59 |
60 |
61 |
62 |

63 |
Loading...Please wait
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/page/project.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
33 |
34 |
37 |
38 |
39 | | 名称 |
40 | 时间 |
41 | 状态 |
42 | 操作 |
43 |
44 |
45 |
46 |
47 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
61 |
62 |
63 |

64 |
Loading...Please wait
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/page/history.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
33 |
34 |
37 |
38 |
39 | | 标题 |
40 | 资源 |
41 | 类型 |
42 | 时间 |
43 | 操作 |
44 |
45 |
46 |
47 |
48 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
61 |
62 |
63 |

64 |
Loading...Please wait
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/page/setting.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
33 |
34 |
37 |
38 |
39 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
64 |
65 |
66 |
67 |
68 |

69 |
Loading...Please wait
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/page/js/history.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 |
3 | var uid = localStorage['id'];
4 |
5 | var getHistory = function() {
6 | $('#modal-loading').modal('show');
7 | $.ajax({
8 | type: "GET",
9 | url: "history/" + uid + '/',
10 | dataType: "json"
11 | }).done(function(json) {
12 | if (!json.succ)
13 | alert(json.errmsg);
14 | else
15 | loadHistory(json.data);
16 | $('#modal-loading').modal('hide');
17 | }).fail(function(data) {
18 | alert('Network error!');
19 | $('#modal-loading').modal('hide');
20 | });
21 | };
22 |
23 |
24 | var loadHistory = function(list) {
25 |
26 | $('.history-row').remove();
27 |
28 | for(var i = 0; i < list.length; i++)
29 | {
30 | var elem = list[i];
31 | var url = getUrl() + '/Entity/' + elem.rsrc + '/';
32 |
33 | var $tr = $('
');
34 | $tr.attr('data-id', elem.id);
35 | var $titleTd = $('' + (elem.title || elem.id) + ' | ');
36 | var $rsrcTd = $('' + elem.rsrc + ' | ');
37 | var $typeTd = $('' + algoDict[elem.type] + ' | ');
38 | var $timeTd = $('' + elem.time + ' | ');
39 | var $opTd = $(' | ');
40 | var $viewAnchor = $('查看');
41 | var $csvAnchor = $('导出');
42 |
43 | $opTd.append($viewAnchor);
44 | $opTd.append(' ');
45 | $opTd.append($csvAnchor);
46 | $tr.append($titleTd);
47 | $tr.append($rsrcTd);
48 | $tr.append($typeTd);
49 | $tr.append($timeTd);
50 | $tr.append($opTd);
51 | $('#history-table').append($tr);
52 | }
53 |
54 | $('.view-result').click(viewResult);
55 | redirToResult(location.hash.slice(1));
56 | }
57 |
58 | var viewResult = function() {
59 | event.preventDefault();
60 | var id = $(this).parent().parent().attr('data-id');
61 | var rsrc = $(this).parent().parent().children('.history-rsrc').text();
62 | var type = $(this).parent().parent().children('.history-type').attr('data-type');
63 | localStorage.setItem('resultId', id);
64 | localStorage.setItem('resultRsrc', rsrc);
65 | localStorage.setItem('resultType', type);
66 | location.href = './result.html';
67 | }
68 |
69 | var redirToResult = function(id) {
70 | if(!id) return;
71 | var $li = $('.history-row');
72 | for(var i = 0; i < $li.length; i++) {
73 | $row = $li.eq(i);
74 | if($row.attr('data-id') == id)
75 | $row.find('.view-result').click();
76 | }
77 | };
78 |
79 | getHistory();
80 | });
--------------------------------------------------------------------------------
/page/js/rsrc.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 |
3 | var getRsrc = function() {
4 |
5 | $('#modal-loading').modal('show');
6 | var proj = localStorage.getItem('proj');
7 | var token = localStorage.getItem('token');
8 | $('#proj-name').text(proj);
9 |
10 | var user = getUser();
11 | var url = getUrl() + "/System/Resource/list?userid=" + user.id + "&project=" + token + '/' + proj;
12 | $.ajax({
13 | type: "GET",
14 | url: url,
15 | dataType: "xml",
16 | beforeSend: function (request) {
17 | request.setRequestHeader("passwd", user.pw);
18 | }
19 | }).done(function(data){
20 | var $data = $(data);
21 | var errmsg = $data.find("error").text();
22 | if (errmsg.length !== 0)
23 | alert(errmsg);
24 | else
25 | loadRsrc($(data).find("resource"));
26 | $('#modal-loading').modal('hide');
27 | }).fail(function(data, status, e){
28 | alert("network error");
29 | $('#modal-loading').modal('hide');
30 | });
31 | };
32 |
33 | var loadRsrc = function($list) {
34 | $('.rsrc-row').remove();
35 | for(var i = 0; i < $list.length; i++)
36 | {
37 | var $item = $list.eq(i);
38 | var name = $item.children('name').text();
39 | var status = $item.children('state').text();
40 | status = (status == 'loaded')? '√': '×';
41 | var lastModified = $item.children('lastmodified').text();
42 |
43 | var $tr = $('
');
44 | var $nameTd = $('' + name + ' | ');
45 | var $statusTd = $('' + status + ' | ');
46 | var $lastTd = $('' + lastModified + ' | ');
47 | var $opTd = $(' | ');
48 | var $viewAnchor = $('查看');
49 | var $mineAnchor = $('挖掘');
50 | $opTd.append($viewAnchor);
51 | $opTd.append(' ');
52 | $opTd.append($mineAnchor);
53 | $tr.append($nameTd);
54 | $tr.append($statusTd);
55 | $tr.append($lastTd);
56 | $tr.append($opTd);
57 | $('#rsrc-table').append($tr);
58 | }
59 | $('.rsrc-view').click(viewRsrc);
60 | $('.rsrc-mine').click(mineRsrc);
61 | };
62 |
63 |
64 | var viewRsrc = function() {
65 | event.preventDefault()
66 | var token = localStorage.getItem('token');
67 | var proj = localStorage.getItem('proj');
68 | var rsrc = $(this).parent().parent().children('.rsrc-name').text();
69 | window.open(getUrl() + '/Entity/' + token + '/' + proj + '/' + rsrc + '/')
70 | };
71 |
72 | var mineRsrc = function() {
73 | event.preventDefault()
74 | var rsrc = $(this).parent().parent().children('.rsrc-name').text();
75 | localStorage.setItem('rsrc', rsrc);
76 | location.href = './mining.html';
77 | };
78 |
79 | getRsrc();
80 | });
--------------------------------------------------------------------------------
/page/js/message.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 |
3 | var uid = localStorage['id'];
4 |
5 | var getMessage = function(all) {
6 |
7 | $('#modal-loading').modal('show');
8 | var url = "message/" + uid + '/';
9 | if(all) url += 'all/';
10 |
11 | $.ajax({
12 | type: "GET",
13 | url: url,
14 | dataType: "json"
15 | }).done(function(json) {
16 | if (!json.succ)
17 | alert(json.errmsg);
18 | else
19 | loadMessage(json.data);
20 | $('#modal-loading').modal('hide');
21 | }).fail(function(data) {
22 | alert('Network error!');
23 | $('#modal-loading').modal('hide');
24 | });
25 | };
26 |
27 | var loadMessage = function(list) {
28 | if(list.length == 0) {
29 | $('#msg-li').append('您目前没有任何消息
');
30 | return;
31 | }
32 |
33 | $('.msg-well').remove();
34 | for(var i = 0; i < list.length; i++) {
35 | var elem = list[i];
36 | var hid = /ID:(\d+)/.exec(elem.content)[1];
37 |
38 | var $well = $('');
39 | $well.attr('data-id', elem.id);
40 | if(elem.isread) $well.addClass('msg-read');
41 | $link = $('');
42 | $link.text(elem.content);
43 | $well.append($link);
44 |
45 | if(!elem.isread) {
46 | $markSpan = $('标记已读')
47 | $well.append($markSpan);
48 | }
49 |
50 | $tmSpan = $('');
51 | $tmSpan.text(elem.tm);
52 | $well.append($tmSpan);
53 |
54 | $('#msg-li').append($well);
55 | }
56 | $('.msg-mark').click(markRead);
57 | //$('.msg-link').click(viewResult);
58 | };
59 |
60 | var markRead = function() {
61 | event.preventDefault();
62 | var $well = $(this).parent()
63 | var id = $well.attr('data-id');
64 |
65 | $.ajax({
66 | type: "GET",
67 | url: 'message/' + uid + '/mark/' + id + '/',
68 | dataType: "json"
69 | }).done(function(json) {
70 | if (!json.succ)
71 | alert(json.errmsg);
72 | else {
73 | $well.fadeOut("normal",function(){this.remove()});
74 | }
75 | }).fail(function(data) {
76 | alert('Network error!');
77 | });
78 | }
79 |
80 | /*var viewResult = function() {
81 | event.preventDefault();
82 | id = /ID:(\d+)/.exec($(this).text())[1];
83 | $.ajax({
84 | type: "GET",
85 | url: "history/" + uid + '/' + id + '/',
86 | dataType: "json"
87 | }).done(function(json) {
88 | if (!json.succ)
89 | alert(json.errmsg);
90 | else {
91 | localStorage.setItem('resultId', id);
92 | localStorage.setItem('resultRsrc', json.data[0].rsrc);
93 | localStorage.setItem('resultType', json.data[0].type);
94 | location.href = './result.html';
95 | }
96 | }).fail(function(data) {
97 | alert('Network error!');
98 | });
99 | }*/
100 |
101 | getMessage(false);
102 | });
--------------------------------------------------------------------------------
/dm/k_medoids.py:
--------------------------------------------------------------------------------
1 | '''
2 | Another clusting method , k-medoids.
3 | See more : http://en.wikipedia.org/wiki/K-medoids
4 | The most common realisation of k-medoid clustering is the Partitioning Around Medoids (PAM) algorithm and is as follows:[2]
5 | 1. Initialize: randomly select k of the n data points as the medoids
6 | 2. Associate each data point to the closest medoid. ("closest" here is defined using any valid distance metric, most commonly Euclidean distance, Manhattan distance or Minkowski distance)
7 | 3. For each medoid m
8 | For each non-medoid data point o
9 | Swap m and o and compute the total cost of the configuration
10 | 4. Select the configuration with the lowest cost.
11 | 5. repeat steps 2 to 4 until there is no change in the medoid.
12 | '''
13 | from clusterBase import importData, pearson_distance
14 | from sklearn import datasets
15 | import random
16 |
17 | iris = datasets.load_iris()
18 |
19 | distances_cache = {}
20 |
21 | def totalcost(blogwords, costf, medoids_idx) :
22 | size = len(blogwords)
23 | total_cost = 0.0
24 | medoids = {}
25 | for idx in medoids_idx :
26 | medoids[idx] = []
27 | for i in range(size) :
28 | choice = None
29 | min_cost = 2.1
30 | for m in medoids :
31 | tmp = distances_cache.get((m,i),None)
32 | if tmp is None :
33 | tmp = pearson_distance(blogwords[m],blogwords[i])
34 | distances_cache[(m,i)] = tmp
35 | if tmp < min_cost :
36 | choice = m
37 | min_cost = tmp
38 | medoids[choice].append(i)
39 | total_cost += min_cost
40 | return total_cost, medoids
41 |
42 |
43 | def kmedoids(blogwords, k=8) :
44 | size = len(blogwords)
45 | medoids_idx = random.sample([i for i in range(size)], k)
46 | pre_cost, medoids = totalcost(blogwords,pearson_distance,medoids_idx)
47 | print pre_cost
48 | current_cost = 2.1 * size # maxmum of pearson_distances is 2.
49 | best_choice = []
50 | best_res = {}
51 | iter_count = 0
52 | while 1 :
53 | for m in medoids :
54 | for item in medoids[m] :
55 | if item != m :
56 | idx = medoids_idx.index(m)
57 | swap_temp = medoids_idx[idx]
58 | medoids_idx[idx] = item
59 | tmp,medoids_ = totalcost(blogwords,pearson_distance,medoids_idx)
60 | #print tmp,'-------->',medoids_.keys()
61 | if tmp < current_cost :
62 | best_choice = list(medoids_idx)
63 | best_res = dict(medoids_)
64 | current_cost = tmp
65 | medoids_idx[idx] = swap_temp
66 | iter_count += 1
67 | print current_cost,iter_count
68 | if best_choice == medoids_idx : break
69 | if current_cost <= pre_cost :
70 | pre_cost = current_cost
71 | medoids = best_res
72 | medoids_idx = best_choice
73 |
74 |
75 | return current_cost, best_choice, best_res
76 |
77 | def print_match(best_medoids, blognames) :
78 | for medoid in best_medoids :
79 | print blognames[medoid],'----->',
80 | for m in best_medoids[medoid] :
81 | print '(',m,blognames[m],')',
82 | print
83 | print '---------' * 20
84 |
85 | if __name__ == '__main__' :
86 | '''
87 | blogwords, blognames = importData()
88 | best_cost,best_choice,best_medoids = kmedoids(blogwords,8)
89 | print_match(best_medoids,blognames)
90 | '''
91 | #print iris
92 | _, center, res = kmedoids(iris.data, 8)
93 | print center, "\n", res
94 |
--------------------------------------------------------------------------------
/dm/preprocess.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import math
3 |
4 | def distinct(rawData):
5 |
6 | def key(row):
7 | newRow = dict(row)
8 | del newRow['id']
9 | return newRow
10 |
11 | result = [dict(row) for row in rawData]
12 | result.sort(key=key)
13 |
14 | left = 0
15 | for right in xrange(1, len(result)):
16 | if key(result[left]) != key(result[right]) \
17 | and left + 1 != right:
18 | left += 1
19 | result[left] = result[right]
20 | print left + 1
21 | return result[0:left + 1]
22 |
23 | def removeAbsence(data):
24 | return [row[:] for row in data if None not in row]
25 |
26 | def fillAbsenceWithVal(data, val):
27 | result = []
28 | for row in data:
29 | result.append([x if x is not None else val for x in row])
30 | return result
31 |
32 | def fillAbsenceWithAvg(data):
33 | result = [row[:] for row in data]
34 | wid = len(result[0])
35 | hei = len(result)
36 | avg = [0] * wid
37 | num = [0] * wid
38 | for row in result:
39 | for i in xrange(wid):
40 | elem = row[i];
41 | if elem is not None:
42 | avg[i] += elem
43 | num[i] += 1
44 | for i in xrange(wid):
45 | if(num[i] != 0):
46 | avg[i] /= num[i]
47 | for row in result:
48 | for i in xrange(wid):
49 | if row[i] is None:
50 | row[i] = avg[i]
51 | return result
52 |
53 | def maxMinRestrict(data):
54 | result = [row[:] for row in data]
55 | wid = len(result[0])
56 | hei = len(result)
57 | maxList = [-1] * wid
58 | minList = [float('inf')] * wid
59 | for row in result:
60 | for i in xrange(wid):
61 | elem = row[i]
62 | if elem is None: continue
63 | if abs(row[i]) > maxList[i]:
64 | maxList[i] = abs(row[i])
65 | if abs(row[i]) < minList[i]:
66 | minList[i] = abs(row[i])
67 | for row in result:
68 | for i in xrange(wid):
69 | elem = row[i]
70 | if elem is None: continue
71 | row[i] = (elem - minList[i]) / (maxList[i] - minList[i])
72 | return result
73 |
74 | def zScoreRestrict(data):
75 | result = [row[:] for row in data]
76 | wid = len(result[0])
77 | hei = len(result)
78 | avg = [0] * wid
79 | avgpow2 = [0] * wid
80 | num = [0] * wid
81 | for row in result:
82 | for i in xrange(wid):
83 | elem = row[i];
84 | if elem is not None:
85 | avg[i] += elem
86 | avgpow2[i] += elem ** 2
87 | num[i] += 1
88 | for i in xrange(wid):
89 | if(num[i] != 0):
90 | avg[i] /= num[i]
91 | avgpow2[i] /= num[i]
92 | sigma = [(avgpow2[i] - avg[i] ** 2) ** 0.5 for i in xrange(wid)]
93 | for row in result:
94 | for i in xrange(wid):
95 | elem = row[i]
96 | if elem is None: continue
97 | row[i] = (elem - avg[i]) / sigma[i]
98 | return result
99 |
100 | def getBit(num):
101 | num = abs(num)
102 | if(num < 1): return 0
103 | else: return math.floor(math.log10(num)) + 1
104 |
105 | def demicalRestrict(data):
106 | result = [row[:] for row in data]
107 | wid = len(result[0])
108 | hei = len(result)
109 | bits = [0] * wid
110 | for row in result:
111 | for i in xrange(wid):
112 | elem = row[i]
113 | if elem is None: continue
114 | bit = getBit(elem)
115 | if bit > bits[i]:
116 | bits[i] = bit
117 | for row in result:
118 | for i in xrange(wid):
119 | elem = row[i]
120 | if elem is None: continue
121 | row[i] = elem / 10 ** bits[i]
122 | return result
--------------------------------------------------------------------------------
/page/result.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
33 |
34 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
59 |
60 |
61 |
62 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
78 |
79 |
80 |
81 |
82 |
83 |
86 |
87 |
88 |
89 |
90 |

91 |
Loading...Please wait
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/rmp_simulator.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from flask import request, make_response
4 |
5 | import sys
6 | reload(sys)
7 | sys.setdefaultencoding('utf-8')
8 |
9 | import json
10 | json.stringify = json.dumps
11 | json.parse = json.loads
12 |
13 | def iris(token, proj):
14 | from sklearn import datasets
15 | iris = datasets.load_iris()
16 | r = []
17 | for i in xrange(len(iris.data)):
18 | row = iris.data[i]
19 | elem = {
20 | "id": i,
21 | "col0": int(row[0] * 10) / 10.0,
22 | "col1": int(row[1] * 10) / 10.0,
23 | "col2": int(row[2] * 10) / 10.0,
24 | "col3": int(row[3] * 10) / 10.0,
25 | "label": iris.target[i]
26 | }
27 | r.append(elem)
28 | return json.stringify({'Iris': r})
29 |
30 | def cart(token, proj):
31 | from dm import loadCart
32 | cart = loadCart()
33 | r = []
34 | id = 0
35 | for row in cart:
36 | elem = {
37 | "id": id,
38 | "col0": row[0],
39 | "col1": row[1],
40 | "col2": row[2],
41 | "col3": row[3]
42 | }
43 | r.append(elem)
44 | id += 1
45 | return make_response(json.stringify({"Cart": r}))
46 |
47 | def getProj():
48 | return """
49 |
50 |
51 | U7f2d2f8faaa9/proj
52 |
53 | 4
54 |
55 |
56 | """
57 |
58 | def getRsrcList():
59 | return """
60 |
61 |
62 | Iris
63 | Tue May 17 2016 10:46:43
64 | loaded
65 |
66 |
67 | Cart
68 | Tue May 17 2016 10:46:43
69 | loaded
70 |
71 |
72 | """
73 |
74 | def getRsrc():
75 | rsrc = request.args.get('resource')
76 | if rsrc == 'Iris':
77 | return """
78 |
79 |
80 | col0
81 |
82 |
83 |
84 | Number
85 |
86 |
87 | col1
88 |
89 |
90 |
91 | Number
92 |
93 |
94 | col2
95 |
96 |
97 |
98 | Number
99 |
100 |
101 | col3
102 |
103 |
104 |
105 | Number
106 |
107 |
108 | label
109 |
110 |
111 |
112 | Number
113 |
114 |
115 | """
116 | elif rsrc == 'Cart':
117 | return """
118 |
119 |
120 | col0
121 |
122 | 50
123 |
124 | String
125 |
126 |
127 | col1
128 |
129 | 50
130 |
131 | String
132 |
133 |
134 | col2
135 |
136 | 50
137 |
138 | String
139 |
140 |
141 | col3
142 |
143 | 50
144 |
145 | String
146 |
147 |
148 | """
149 | else:
150 | return """
151 |
152 | Column not found!
153 |
154 | """
155 |
156 | def login():
157 | return json.stringify({"error": None, "id": 233837063867287})
--------------------------------------------------------------------------------
/dm/apriori.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | def loadDataSet():
4 | '''
5 | 创建一个用于测试的简单的数据集
6 | '''
7 | return [
8 | [ '豆奶', '莴苣' ],
9 | [ '莴苣', '尿布', '葡萄酒', '甜菜' ],
10 | [ '莴苣', '尿布', '葡萄酒', '橙汁' ],
11 | [ '莴苣', '豆奶', '尿布', '葡萄酒' ],
12 | [ '莴苣', '豆奶', '尿布', '橙汁' ]
13 | ]
14 |
15 | def createC1( dataSet ):
16 | '''
17 | 构建初始候选项集的列表,即所有候选项集只包含一个元素,
18 | C1是大小为1的所有候选项集的集合
19 | '''
20 | C1 = []
21 | for transaction in dataSet:
22 | for item in transaction:
23 | if [ item ] not in C1:
24 | C1.append( [ item ] )
25 | C1.sort()
26 | return map( frozenset, C1 )
27 | def scanD( D, Ck, minSupport ):
28 | '''
29 | 计算Ck中的项集在数据集合D(记录或者transactions)中的支持度,
30 | 返回满足最小支持度的项集的集合,和所有项集支持度信息的字典。
31 | '''
32 | ssCnt = {}
33 | for tid in D:
34 | # 对于每一条transaction
35 | for can in Ck:
36 | # 对于每一个候选项集can,检查是否是transaction的一部分
37 | # 即该候选can是否得到transaction的支持
38 | if can.issubset( tid ):
39 | ssCnt[ can ] = ssCnt.get( can, 0) + 1
40 | numItems = float( len( D ) )
41 | retList = []
42 | supportData = {}
43 | for key in ssCnt:
44 | # 每个项集的支持度
45 | support = ssCnt[ key ] / numItems
46 | # 将满足最小支持度的项集,加入retList
47 | if support >= minSupport:
48 | retList.insert( 0, key )
49 | # 汇总支持度数据
50 | supportData[ key ] = support
51 | return retList, supportData
52 |
53 | # Aprior算法
54 | def aprioriGen( Lk, k ):
55 | '''
56 | 由初始候选项集的集合Lk生成新的生成候选项集,
57 | k表示生成的新项集中所含有的元素个数
58 | '''
59 | retList = []
60 | lenLk = len( Lk )
61 | for i in range( lenLk ):
62 | for j in range( i + 1, lenLk ):
63 | L1 = list( Lk[ i ] )[ : k - 2 ];
64 | L2 = list( Lk[ j ] )[ : k - 2 ];
65 | L1.sort();L2.sort()
66 | if L1 == L2:
67 | retList.append( Lk[ i ] | Lk[ j ] )
68 | return retList
69 | def _apriori( dataSet, minSupport = 0.5 ):
70 | # 构建初始候选项集C1
71 | C1 = createC1( dataSet )
72 | # 将dataSet集合化,以满足scanD的格式要求
73 | D = map( set, dataSet )
74 | # 构建初始的频繁项集,即所有项集只有一个元素
75 | L1, suppData = scanD( D, C1, minSupport )
76 | L = [ L1 ]
77 | # 最初的L1中的每个项集含有一个元素,新生成的
78 | # 项集应该含有2个元素,所以 k=2
79 | k = 2
80 | while ( len( L[ k - 2 ] ) > 0 ):
81 | Ck = aprioriGen( L[ k - 2 ], k )
82 | Lk, supK = scanD( D, Ck, minSupport )
83 | # 将新的项集的支持度数据加入原来的总支持度字典中
84 | suppData.update( supK )
85 | # 将符合最小支持度要求的项集加入L
86 | L.append( Lk )
87 | # 新生成的项集中的元素个数应不断增加
88 | k += 1
89 | # 返回所有满足条件的频繁项集的列表,和所有候选项集的支持度信息
90 | return L, suppData
91 |
92 | # 规则生成与评价
93 | def calcConf( freqSet, H, supportData, brl, minConf=0.7 ):
94 | '''
95 | 计算规则的可信度,返回满足最小可信度的规则。
96 | freqSet(frozenset):频繁项集
97 | H(frozenset):频繁项集中所有的元素
98 | supportData(dic):频繁项集中所有元素的支持度
99 | brl(tuple):满足可信度条件的关联规则
100 | minConf(float):最小可信度
101 | '''
102 | prunedH = []
103 | for conseq in H:
104 | freqSetSupport = supportData[ freqSet ]
105 | srcSupport = supportData[ freqSet - conseq ]
106 | conf = freqSetSupport / srcSupport
107 | if conf >= minConf:
108 | brl.append( ( freqSet - conseq, conseq, conf, freqSetSupport, srcSupport ) )
109 | prunedH.append( conseq )
110 | return prunedH
111 | def rulesFromConseq( freqSet, H, supportData, brl, minConf=0.7 ):
112 | '''
113 | 对频繁项集中元素超过2的项集进行合并。
114 | freqSet(frozenset):频繁项集
115 | H(frozenset):频繁项集中的所有元素,即可以出现在规则右部的元素
116 | supportData(dict):所有项集的支持度信息
117 | brl(tuple):生成的规则
118 | '''
119 | m = len( H[ 0 ] )
120 | # 查看频繁项集是否大到移除大小为 m 的子集
121 | if len( freqSet ) > m + 1:
122 | Hmp1 = aprioriGen( H, m + 1 )
123 | Hmp1 = calcConf( freqSet, Hmp1, supportData, brl, minConf )
124 | # 如果不止一条规则满足要求,进一步递归合并
125 | if len( Hmp1 ) > 1:
126 | rulesFromConseq( freqSet, Hmp1, supportData, brl, minConf )
127 | def generateRules( L, supportData, minConf=0.7 ):
128 | '''
129 | 根据频繁项集和最小可信度生成规则。
130 | L(list):存储频繁项集
131 | supportData(dict):存储着所有项集(不仅仅是频繁项集)的支持度
132 | minConf(float):最小可信度
133 | 返回值:( freqSet - conseq, conseq, conf )的数组
134 | '''
135 | bigRuleList = []
136 | for i in range( 1, len( L ) ):
137 | for freqSet in L[ i ]:
138 | # 对于每一个频繁项集的集合freqSet
139 | H1 = [ frozenset( [ item ] ) for item in freqSet ]
140 | # 如果频繁项集中的元素个数大于2,需要进一步合并
141 | if i > 1:
142 | rulesFromConseq( freqSet, H1, supportData, bigRuleList, minConf )
143 | else:
144 | calcConf( freqSet, H1, supportData, bigRuleList, minConf )
145 | return bigRuleList
146 |
147 |
148 | def apriori(dataSet, **kwargs):
149 | minSupport = kwargs.get('minSupport')
150 | if minSupport is None: minSupport = 0.5
151 | minConf = kwargs.get('minConf')
152 | if minConf is None: minConf = 0.7
153 | L, suppData = _apriori(dataSet, minSupport)
154 | return generateRules(L, suppData, minConf)
155 |
156 | def printRules(rules):
157 | for row in rules:
158 | print '{0} ----> {1} conf: {2} support: {3}, {4}'.format(
159 | ', '.join(row[0]),
160 | ', '.join(row[1]),
161 | row[2],
162 | row[3],
163 | row[4]
164 | )
165 |
166 | if __name__ == '__main__':
167 | myDat = loadDataSet()
168 | rules = apriori(myDat)
169 | printRules(rules)
--------------------------------------------------------------------------------
/page/js/util.js:
--------------------------------------------------------------------------------
1 | function getUrl() {
2 | return 'http://202.120.40.73:28080';
3 | //return 'http://localhost:5000';
4 | }
5 |
6 | function getUser() {
7 | var id = localStorage.getItem('id');
8 | var un = localStorage.getItem('un');
9 | var pw = localStorage.getItem('pw');
10 |
11 | if(id && un && pw)
12 | return {
13 | id: id,
14 | un: un,
15 | pw: pw
16 | }
17 | else return null;
18 | }
19 |
20 | function setUser(id, un, pw) {
21 | localStorage.setItem('id', id);
22 | localStorage.setItem('un', un);
23 | localStorage.setItem('pw', pw);
24 | }
25 |
26 | function htmlSpecialChars(s) {
27 | return s.replace(//g, '>')
29 | .replace(/&/g, '&')
30 | .replace(/"/g, '"')
31 | .replace(/'/g, ''');
32 | }
33 |
34 | var statusMap = {
35 | 1: 'View Resouce',
36 | 2: 'Manage Resource',
37 | 3: 'Delete Object',
38 | 4: 'Previlege Assignment'
39 | };
40 |
41 | var algos = {
42 | assoc: ['apriori'],
43 | classify: ['knn', 'svm', 'naive_bayes'],
44 | cluster: ['kmeans', 'kmedoids']
45 | };
46 |
47 | var algoDict = {
48 | assoc: "关联",
49 | classify: "分类",
50 | cluster: "聚类",
51 | apriori: "Apriori",
52 | knn: "KNN",
53 | svm: "SVM",
54 | naive_bayes: "Naive Bayes",
55 | kmeans: "Kmeans",
56 | kmedoids: "Kmedoids"
57 | };
58 |
59 | var $getPagBtn = function(data, text) {
60 | return $('');
63 | };
64 |
65 | var pageCap = 10;
66 |
67 | var loadPagBar = function(cur, total, data) {
68 | if(cur > total) throw new Error();
69 |
70 | $('#pag-bar').empty();
71 | var pages;
72 | if(cur == 1 || cur == 2)
73 | pages = [1, 2, 3, 4, 5];
74 | else if(cur == total || cur == total - 1)
75 | pages = [total - 4, total - 3, total - 2, total - 1, total];
76 | else
77 | pages = [cur - 2, cur - 1, cur, cur + 1, cur + 2];
78 | pages = pages.filter(function(x){return x > 0 && x <= total;});
79 |
80 | var result = [];
81 | if(cur != 1) {
82 | var $prev = $getPagBtn(cur - 1, '上一页');
83 | $prev.addClass('pag-prev');
84 | result.push($prev);
85 | }
86 |
87 |
88 | var $nums = $('');
89 | result.push($nums);
90 | if(pages.indexOf(1) == -1) {
91 | $getPagBtn(1, 1).appendTo($nums);
92 | $getPagBtn('', '...').appendTo($nums);
93 | }
94 |
95 | for(var i in pages) {
96 | $getPagBtn(pages[i], pages[i]).appendTo($nums);
97 | }
98 |
99 | if(pages.indexOf(total) == -1) {
100 | $getPagBtn('', '...').appendTo($nums);
101 | $getPagBtn(total, total).appendTo($nums);
102 | }
103 |
104 | if(cur != total && total != 1) {
105 | var $next = $getPagBtn(cur + 1, '下一页');
106 | $next.addClass('pag-next');
107 | result.push($next);
108 | }
109 |
110 | for(var i = 0; i < result.length; i++)
111 | $('#pag-bar').append(result[i]);
112 | $('.pag-btn').click(function(){refreshPage.call(this, total, data)});
113 | };
114 |
115 | var refreshPage = function(total, data) {
116 | var pg = $(this).data('pg');
117 | if(pg == '') return;
118 | loadPagBar(pg, total, data);
119 | loadResult(data.slice((pg - 1) * pageCap, pg * pageCap));
120 | };
121 |
122 | var keys = function(o) {
123 | var keys = [];
124 | for(var k in o)
125 | keys.push(k);
126 | return keys;
127 | };
128 |
129 | var values = function(o) {
130 | var values = [];
131 | for(var k in o)
132 | values.push(o[k]);
133 | return values;
134 | };
135 |
136 | var labelToColor = function(i) {
137 | var m = [
138 | "#993", "#C9C", "#C96", "#666", "#C99", "#CC9", "#333", "#96C"
139 | ];
140 |
141 | return m[i % m.length];
142 | };
143 |
144 | // 阻塞延迟
145 | function sleep(milliSeconds) {
146 | var startTime = new Date().getTime();
147 | while (new Date().getTime() < startTime + milliSeconds);
148 | }
149 |
150 | // 两点连线与x轴的夹角,如果两点相同返回0
151 | function slopeAngle(p1, p2) {
152 | var angle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
153 | if (angle < 0) angle += Math.PI * 2;
154 | return angle;
155 | }
156 |
157 |
158 | function distance(p1, p2) {
159 | return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2));
160 | }
161 |
162 | // 返回最下面的点,如果y值相同则返回左边的点
163 | function findMostLeftBottom(arr) {
164 | if(arr.length == 0) throw new Error();
165 | var res = arr[0];
166 | for(var i = 1; i < arr.length; i++) {
167 | var p = arr[i];
168 | if(p.y < res.y || (p.y == res.y && p.x < res.x))
169 | res = p;
170 | }
171 | return res;
172 | }
173 |
174 | // Graham扫描算法
175 | function graham(arr) {
176 |
177 | arr = arr.slice();
178 | var lbMost = findMostLeftBottom(arr);
179 | var pos = arr.indexOf(lbMost);
180 | arr.splice(pos, 1);
181 |
182 | arr.sort(function(p1, p2) {
183 | var theta1 = slopeAngle(lbMost, p1);
184 | var theta2 = slopeAngle(lbMost, p2);
185 | if(theta1 != theta2)
186 | return theta1 - theta2;
187 | else
188 | return distance(p1, lbMost) - distance(p2, lbMost);
189 | })
190 |
191 | var res = [lbMost];
192 | for(var i = 0; i < arr.length; i++) {
193 | var p = arr[i];
194 | if(res.length < 3)
195 | res.push(p);
196 | else {
197 | var p1 = res[res.length - 2],
198 | p2 = res[res.length - 1];
199 | var theta1 = slopeAngle(p1, p2),
200 | theta2 = slopeAngle(p2, p);
201 | if(theta1 < theta2) // 左转保留
202 | res.push(p);
203 | else // 右转舍弃
204 | {
205 | res.pop();
206 | i--;
207 | }
208 | }
209 | }
210 | return res;
211 | }
212 |
213 | var getTimeStr = function(tm) {
214 |
215 | var tm = tm || new Date();
216 | var o = {
217 | yr: tm.getFullYear(),
218 | mon: tm.getMonth() + 1,
219 | dt: tm.getDate(),
220 | hr: tm.getHours(),
221 | min: tm.getMinutes(),
222 | sec: tm.getSeconds()
223 | };
224 | for(var i in o)
225 | {
226 | o[i] = o[i].toString();
227 | if(o[i].length < 2)
228 | o[i] = '0' + o[i];
229 | }
230 | return o.yr + '-' + o.mon + '-' + o.dt +
231 | ' ' + o.hr + ':' + o.min + ':' + o.sec;
232 | };
--------------------------------------------------------------------------------
/page/js/mining.js:
--------------------------------------------------------------------------------
1 | $(function(){
2 |
3 | var selected = {};
4 |
5 |
6 | var getCols = function() {
7 |
8 | $('#modal-loading').modal('show');
9 | var user = getUser();
10 | var proj = localStorage.getItem('proj');
11 | var token = localStorage.getItem('token');
12 | var rsrc = localStorage.getItem('rsrc');
13 | $('#rsrc-name').text(rsrc);
14 |
15 | var url = getUrl() + '/System/Resource?userid=' + user.id + '&project=' +
16 | token + '/' + proj + '&resource=' + rsrc
17 | $.ajax({
18 | type: "GET",
19 | url: url,
20 | dataType: "xml",
21 | beforeSend: function (request) {
22 | request.setRequestHeader("passwd", user.pw);
23 | }
24 | }).done(function(data){
25 | var $data = $(data);
26 | var errmsg = $data.find("error").text();
27 | if (errmsg.length !== 0)
28 | alert(errmsg);
29 | else
30 | loadCols($(data).find("Column"));
31 | $('#modal-loading').modal('hide');
32 | }).fail(function(data, status, e){
33 | alert("network error");
34 | $('#modal-loading').modal('hide');
35 | });
36 | };
37 |
38 | var loadCols = function($list) {
39 | $('.cols-row').remove();
40 | for(var i = 0; i < $list.length; i++)
41 | {
42 | var $item = $list.eq(i);
43 | var name = $item.children('ColumnName').text();
44 | var alias = $item.children('AttributeName').text() || "(未设置)";
45 | var size = $item.children('Size').text();
46 | //var isNotNull = $item.children('NotNull').text();
47 | var type = $item.children('Type').text();
48 | if(size) type += ' * ' + size;
49 |
50 | var $tr = $('
');
51 | var $nameTd = $('' + name + ' | ');
52 | var $aliasTd = $('' + alias + ' | ');
53 | var $typeTd = $('' + type + ' | ');
54 | var $isNotNullTd = $('是 | ');
55 | var $opTd = $(' | ');
56 | var $selectCheck = $('');
57 | $opTd.append($selectCheck);
58 | $tr.append($nameTd);
59 | $tr.append($aliasTd);
60 | $tr.append($typeTd);
61 | $tr.append($isNotNullTd);
62 | $tr.append($opTd);
63 | $('#cols-table').append($tr);
64 | }
65 | $('.cols-select').click(selectCol);
66 | };
67 |
68 | var selectCol = function() {
69 |
70 | var $this = $(this);
71 | var name = $this.parent().parent().children('.cols-name').text();
72 |
73 | if($this.is(':checked'))
74 | selected[name] = name;
75 | else
76 | delete selected[name];
77 |
78 | console.log(selected);
79 | };
80 |
81 | var mining = function() {
82 |
83 | var uid = localStorage['id'];
84 | var proj = localStorage.getItem('proj');
85 | var token = localStorage.getItem('token');
86 | var rsrc = localStorage.getItem('rsrc');
87 |
88 | var type = $('#type-combo').val();
89 | var algo = $('#algo-combo').val();
90 | var start = $('#start-num').val();
91 | var count = $('#count-num').val();
92 | if(count == "-1") count = "";
93 |
94 | var title = $('#title-txt').val();
95 | if(title == "")
96 | {
97 | alert('名称不能为空!');
98 | return;
99 | }
100 |
101 | var cols = keys(selected);
102 | if(cols.length == 0)
103 | {
104 | alert('请选择要挖掘的列!');
105 | return;
106 | }
107 | cols = JSON.stringify(cols);
108 |
109 | var args = {}
110 | if(algo == "apriori") {
111 | var minSupport = $('#apriori-min-support').val();
112 | var minConf = $('#apriori-min-conf').val();
113 | minSupport = parseFloat(minSupport);
114 | minConf = parseFloat(minConf);
115 | if(isNaN(minSupport) || isNaN(minConf)) {
116 | alert('参数格式有误!');
117 | return;
118 | }
119 | args = {
120 | minSupport: minSupport,
121 | minConf: minConf
122 | }
123 | }
124 | else if(algo == "kmeans") {
125 | var n_clusters = parseInt($('#kmeans-label-num').val());
126 | var max_iter = parseInt($('#kmeans-max-iter').val());
127 | var init = $('#kmeans-init').val();
128 | var precompute_distances = $('#kmeans-pre-dist').val();
129 | if(precompute_distances != 'auto') precompute_distances = precompute_distances == 'true'
130 | tol = parseFloat($('#kmeans-tol').val());
131 | if(isNaN(n_clusters) || isNaN(max_iter) ||
132 | ['k-means++', 'random'].indexOf(init) == -1 ||
133 | ['auto', true, false].indexOf(precompute_distances) == -1 ||
134 | isNaN(tol)) {
135 | alert('参数格式有误!');
136 | return;
137 | }
138 | args = {
139 | n_clusters: n_clusters,
140 | max_iter: max_iter,
141 | init: init,
142 | precompute_distances: precompute_distances,
143 | tol: tol
144 | };
145 | }
146 | else if(algo == "kmedoids") {
147 | var k = $('#kmedoids-label-num').val();
148 | k = parseInt(k);
149 | if(isNaN(k)) {
150 | alert('参数格式有误!');
151 | return;
152 | }
153 | args = {
154 | k: k
155 | };
156 | }
157 | else if (algo == "svm") {
158 | var C = parseFloat($('#svm-c').val());
159 | var kernel = $('#svm-kernel').val();
160 | var degree = parseInt($('#svm-degree').val());
161 | var gamma = $('#svm-gamma').val();
162 | if(gamma != 'auto') gamma = parseFloat(gamma);
163 | var coef0 = parseFloat($('#svm-coef0').val());
164 | var probability = $('#svm-probability').val() == 'true';
165 | var shrinking = $('#svm-shrinking').val() == 'true';
166 | var tol = parseFloat($('#svm-tol').val());
167 | if(isNaN(C) || isNaN(degree) || (gamma != 'auto' && isNaN(gamma)) ||
168 | isNaN(coef0) || isNaN(tol)) {
169 | alert('参数格式有误!');
170 | return;
171 | }
172 | args = {
173 | C: C,
174 | kernel: kernel,
175 | degree: degree,
176 | gamma: gamma,
177 | coef0: coef0,
178 | probability: probability,
179 | shrinking: shrinking,
180 | tol: tol
181 | }
182 | console.log(args);
183 | }
184 | args = JSON.stringify(args);
185 |
186 | var url = './mining/' + uid + '/' + token + '/' + proj + '/' + rsrc + '/';
187 | var data = 'algo=' + algo + '&start=' + start + "&count=" +
188 | count + '&cols=' + encodeURIComponent(cols) + '&title=' +
189 | encodeURIComponent(title) + '&args=' + encodeURIComponent(args);
190 |
191 | if(type == "classify")
192 | {
193 | var predictStart = $('#predict-start-num').val();
194 | var predictCount = $('#predict-count-num').val();
195 | if(predictCount == "-1") predictCount = "";
196 | var label = $('#predict-label-text').val();
197 | if(label == "")
198 | {
199 | alert('请填写标签。');
200 | return;
201 | }
202 |
203 | data += '&predictStart=' + predictStart + '&predictCount=' +
204 | predictCount + '&label=' + label;
205 | }
206 |
207 | if(type != 'assoc') {
208 | var absent = $('#absent-combo').val();
209 | var fillval = $('#fillval-text').val();
210 | var formal = $('#formal-combo').val();
211 | var distinct = $('#distinct-cb').is(':checked').toString();
212 | data += '&absent=' + absent + '&fillval=' +
213 | fillval + '&formal=' + formal + '&distinct=' + distinct;
214 | }
215 |
216 | $.ajax({
217 | type: "POST",
218 | url: url,
219 | data: data,
220 | dataType: "json",
221 | contentType: "application/x-www-form-urlencoded"
222 | }).done(function(data){
223 | if(!data.succ)
224 | alert(data.msg);
225 | else {
226 | alert('已提交。');
227 | location.href = './history.html';
228 | }
229 | }).fail(function(data, status, e){
230 | alert("network error");
231 | });
232 | };
233 |
234 | var initAlgoType = function() {
235 |
236 | var $typeCombo = $('#type-combo');
237 | for(type in algos)
238 | $('').appendTo($typeCombo);
239 | $typeCombo.on('change', changeAlgoType);
240 | changeAlgoType.call($typeCombo);
241 | var $algoCombo = $('#algo-combo');
242 | $algoCombo.on('change', changeAlgo);
243 | changeAlgo.call($algoCombo);
244 | };
245 |
246 | var changeAlgoType = function() {
247 |
248 | var type = $(this).val();
249 | var $algoCombo = $('#algo-combo');
250 | $algoCombo.empty();
251 | for(var i in algos[type])
252 | {
253 | var algo = algos[type][i];
254 | $('').appendTo($algoCombo);
255 | }
256 |
257 | if(type == "classify")
258 | $('.classify-req').removeClass('hidden');
259 | else
260 | $('.classify-req').addClass('hidden');
261 |
262 | if(type == 'assoc')
263 | $('#prepro-panel').addClass('hidden');
264 | else
265 | $('#prepro-panel').removeClass('hidden')
266 |
267 | $algoCombo.on('change', changeAlgo);
268 | changeAlgo.call($algoCombo);
269 | };
270 |
271 | var absentComboOnClick = function() {
272 | if($('#absent-combo').val() == "val")
273 | $('.fillval').removeClass('hidden');
274 | else
275 | $('.fillval').addClass('hidden');
276 | };
277 |
278 | var changeAlgo = function() {
279 | $('.args').addClass('hidden');
280 | var algo = $('#algo-combo').val();
281 | if(algo == "apriori")
282 | $('#apriori-arg').removeClass('hidden');
283 | else if (algo == "kmeans")
284 | $('#kmeans-arg').removeClass('hidden');
285 | else if (algo == "kmedoids")
286 | $('#kmedoids-arg').removeClass('hidden');
287 | else if (algo == "svm")
288 | $('#svm-arg').removeClass('hidden');
289 | };
290 |
291 | getCols();
292 | initAlgoType();
293 | $('#mining-btn').click(mining);
294 | $('#absent-combo').click(absentComboOnClick);
295 | });
--------------------------------------------------------------------------------
/page/mining.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
33 |
34 |
37 |
38 |
39 | | 名称 |
40 | 别名 |
41 | 类型 |
42 | 是否非空 |
43 | 选定 |
44 |
45 |
46 |
47 |
48 |
49 |
52 |
53 |
61 |
62 |
65 |
66 |
67 |
68 |
71 |
72 |
73 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
85 |
86 |
87 |
88 |
89 |
90 |
93 |
94 |
95 |
96 |
99 |
100 |
101 |
102 |
103 |
104 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
118 |
119 |
120 |
123 |
124 |
130 |
131 |
134 |
135 |
136 |
137 |
138 |
139 |
142 |
143 |
149 |
150 |
151 |
152 |
155 |
156 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
167 |
168 |
169 |
172 |
173 |
174 |
175 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
189 |
190 |
191 |
192 |
195 |
196 |
197 |
198 |
201 |
202 |
206 |
207 |
210 |
211 |
216 |
217 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
242 |
243 |
244 |
245 |
248 |
249 |
256 |
257 |
260 |
261 |
262 |
263 |
266 |
267 |
268 |
269 |
272 |
273 |
274 |
275 |
278 |
279 |
283 |
284 |
287 |
288 |
292 |
293 |
296 |
297 |
298 |
299 |
300 |
305 |
306 |
307 |
308 |
314 |
315 |
318 |
319 |
320 |
321 |
322 |
323 |
326 |
327 |
328 |
329 |
330 |

331 |
Loading...Please wait
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
--------------------------------------------------------------------------------
/page/js/result.js:
--------------------------------------------------------------------------------
1 | $(function() {
2 |
3 | var id = localStorage.getItem('resultId');
4 | var type = localStorage.getItem('resultType');
5 | var rsrc = localStorage.getItem('resultRsrc');
6 | $('#rsrc-name').text(rsrc);
7 |
8 | $resultHeadTr = $('#result-head');
9 | if(type == 'assoc')
10 | {
11 | $('关联规则 | ').appendTo($resultHeadTr);
12 | $('置信度 | ').appendTo($resultHeadTr);
13 | }
14 | else if(type == 'classify' || type == 'cluster')
15 | {
16 | $('id | ').appendTo($resultHeadTr);
17 | $('原始数据 | ').appendTo($resultHeadTr);
18 | $('标签 | ').appendTo($resultHeadTr);
19 | }
20 | else
21 | throw new Error();
22 |
23 | var getResult = function() {
24 |
25 | $('#modal-loading').modal('show');
26 | $.ajax({
27 | type: "GET",
28 | url: "result/" + id + '/',
29 | dataType: "json"
30 | }).done(function(json) {
31 | if (!json.succ)
32 | alert(json.errmsg);
33 | else {
34 | var data = json.data;
35 | if(type != 'assoc')
36 | data = data.map(function(e){return [e[0], e[1], JSON.parse(e[2])]});
37 | //window.data = data;
38 | var totalPage = Math.floor((data.length - 1) / pageCap) + 1;
39 | loadPagBar(1, totalPage, data);
40 | loadResult(data.slice(0, pageCap));
41 | loadCharts(data);
42 | $('#modal-loading').modal('hide');
43 | }
44 | }).fail(function(data) {
45 | alert('Network error!');
46 | $('#modal-loading').modal('hide');
47 | });
48 | };
49 |
50 |
51 | var loadResult = function(list) {
52 |
53 |
54 | $('.result-row').remove();
55 | for (var i = 0; i < list.length; i++) {
56 | var elem = list[i];
57 |
58 | var $tr = $('
')
59 |
60 | if(type == 'assoc')
61 | {
62 | var $ruleTd = $('' + elem[2] + ' | ');
63 | var $confTd = $('' + elem[1] + ' | ');
64 | $tr.append($ruleTd);
65 | $tr.append($confTd);
66 | }
67 | else if(type == 'cluster' || type == 'classify')
68 | {
69 | var dataStr = htmlSpecialChars(formatData(elem[2]));
70 | //var $idTd = $('' + elem[0] + ' | ');
72 | var $idTd = $('' + elem[0] + ' | ');
73 | var $dataTd = $('' + dataStr + ' | ');
74 | var $labelTd = $('' + elem[1] + ' | ');
75 | $tr.append($idTd);
76 | $tr.append($dataTd);
77 | $tr.append($labelTd);
78 | }
79 | else
80 | throw new Error();
81 |
82 | $('#result-table').append($tr);
83 | }
84 | //$('[data-toggle="tooltip"]').tooltip()
85 | };
86 | window.loadResult = loadResult;
87 |
88 | var formatData = function(data) {
89 | var arr = [];
90 | for(var k in data)
91 | arr.push(k + ': ' + data[k]);
92 | return arr.join(', ');
93 | };
94 |
95 | var loadCharts = function(list) {
96 |
97 | if(type == 'cluster' || type == 'classify') {
98 |
99 | var keyList = keys(list[0][2]);
100 |
101 | loadTotalChart(list);
102 | loadDistChart(list, keyList.slice(0, 2));
103 |
104 | var $keyOptions = keyList.map(function(k){return $('');});
105 | $('#col1-combo').append($keyOptions);
106 | $keyOptions = keyList.map(function(k){return $('');});
107 | $('#col2-combo').append($keyOptions);
108 | $('#gen-btn').click(function(){genDistChart(list);});
109 | }
110 | else if(type == 'assoc') {
111 | $('.visual-control').addClass('hidden');
112 | loadTotalChartAssoc(list);
113 | loadDistChartAssoc(list);
114 | }
115 | else
116 | throw new Error();
117 |
118 | };
119 |
120 | var loadTotalChart = function(list) {
121 | $('#total-svg').empty();
122 |
123 | var labelCountMap = {};
124 | for (var i = 0; i < list.length; i++) {
125 | var elem = list[i];
126 | var label = elem[1];
127 | var num = labelCountMap[label] || 0;
128 | labelCountMap[label] = num + 1;
129 | }
130 | var labels = keys(labelCountMap);
131 | var counts = values(labelCountMap);
132 |
133 | var svg = d3.select("#total-svg");
134 | var width = svg.attr("width");
135 | var height = svg.attr("height") - 20;
136 | var xScale = d3.scale.ordinal()
137 | .domain(d3.range(counts.length))
138 | .rangeRoundBands([0, width]);
139 | var yScale = d3.scale.linear()
140 | .domain([0,d3.max(counts)])
141 | .range([height, 0]);
142 | var rectPadding = 4;
143 | var rects = svg.selectAll(".rect")
144 | .data(counts)
145 | .enter()
146 | .append("rect")
147 | //.attr("class", "MyRect")
148 | //.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
149 | .attr("x", function(d,i){
150 | return xScale(i) + rectPadding/2;
151 | } )
152 | .attr("y",function(d){
153 | return yScale(d);
154 | })
155 | .attr("width", xScale.rangeBand() - rectPadding )
156 | .attr("height", function(d){
157 | return height - yScale(d);
158 | })
159 | .attr("fill", function(d, i) {
160 | return labelToColor(labels[i]);
161 | });
162 |
163 | var texts = svg.selectAll(".text")
164 | .data(counts)
165 | .enter()
166 | .append("text")
167 | //.attr("class","MyText")
168 | //.attr("transform","translate(" + padding.left + "," + padding.top + ")")
169 | .attr("x", function(d,i){
170 | return xScale(i) + rectPadding/2;
171 | } )
172 | .attr("y",function(d){
173 | return yScale(d);
174 | })
175 | .attr("dx",function(){
176 | return (xScale.rangeBand() - rectPadding)/2 - 10;
177 | })
178 | .attr("dy", 20)
179 | .text(function(d){
180 | return d;
181 | })
182 | .attr('fill', 'white');
183 |
184 | var texts = svg.selectAll(".label")
185 | .data(labels)
186 | .enter()
187 | .append("text")
188 | //.attr("class","MyText")
189 | //.attr("transform","translate(" + padding.left + "," + padding.top + ")")
190 | .attr("x", function(d,i){
191 | return xScale(i) + rectPadding/2;
192 | } )
193 | .attr("y", height)
194 | .attr("dx",function(){
195 | return (xScale.rangeBand() - rectPadding)/2 - 5;
196 | })
197 | .attr("dy", 20)
198 | .text(function(d){
199 | return d;
200 | })
201 | .attr('fill', 'black');
202 | };
203 |
204 | var genDistChart = function(data) {
205 | var col1 = $('#col1-combo').val();
206 | var col2 = $('#col2-combo').val();
207 | if(!col1 || !col2) return;
208 | loadDistChart(data, [col1, col2]);
209 | };
210 |
211 | var loadDistChart = function(data, cols) {
212 |
213 | $('#dist-svg').empty();
214 |
215 | var xCol = cols[0];
216 | if(!xCol) throw new Error();
217 | var yCol = cols[1] || cols[0];
218 | var xArr = data.map(function(e){return e[2][xCol];})
219 | var yArr = data.map(function(e){return e[2][yCol];})
220 |
221 | var padding = {left: 30, right: 10, top: 10, bottom: 20};
222 | var svg = d3.select("#dist-svg");
223 | var width = svg.attr("width") - padding.left - padding.right;
224 | var height = svg.attr("height") - padding.top - padding.bottom;
225 | var xScale = d3.scale.linear()
226 | .domain([0, d3.max(xArr)])
227 | .range([0, width]);
228 | var yScale = d3.scale.linear()
229 | .domain([0, d3.max(yArr)])
230 | .range([height, 0]);
231 |
232 | var circles = svg.selectAll('.circle')
233 | .data(data)
234 | .enter()
235 | .append("circle")
236 | .attr('cx', function(d) {
237 | return xScale(d[2][xCol]);
238 | console.log(d);
239 | })
240 | .attr('cy', function(d) {
241 | return yScale(d[2][yCol]);
242 | })
243 | .attr('r', 3)
244 | .attr("transform","translate(" + padding.left + "," + padding.top + ")")
245 | .attr('fill', function(d) {
246 | return labelToColor(d[1]);
247 | });
248 |
249 | var yAxis = d3.svg.axis()
250 | .scale(yScale)
251 | .orient("left");
252 | svg.append("g")
253 | .attr("class","axis")
254 | .attr("transform","translate(" + padding.left + "," + padding.top + ")")
255 | .call(yAxis);
256 |
257 | var xAxis = d3.svg.axis()
258 | .scale(xScale)
259 | .orient("bottom");
260 | svg.append("g")
261 | .attr("class","axis")
262 | .attr("transform","translate(" + padding.left + "," + (height + padding.top) + ")")
263 | .call(xAxis);
264 |
265 | // 绘制凸包
266 | var pointsByLabel = {};
267 | for (var i = 0; i < data.length; i++) {
268 | var elem = data[i];
269 | var label = elem[1];
270 | var arr = pointsByLabel[label] || [];
271 | var p = {x: elem[2][xCol], y: elem[2][yCol]};
272 | arr.push(p);
273 | pointsByLabel[label] = arr;
274 | }
275 |
276 | for (var label in pointsByLabel) {
277 | console.log('label: ' + label);
278 | console.log('points: ' + JSON.stringify(pointsByLabel[label]));
279 | var convex = graham(pointsByLabel[label]);
280 | var linesData = [];
281 | for(var i = 0; i < convex.length - 1; i++)
282 | linesData.push([convex[i], convex[i + 1]]);
283 | linesData.push([convex[convex.length - 1], convex[0]]);
284 | console.log('lines: ' + JSON.stringify(linesData));
285 |
286 | var lines = svg.selectAll('.line')
287 | .data(linesData)
288 | .enter()
289 | .append('line')
290 | .attr('x1', function(d) {return xScale(d[0].x);})
291 | .attr('y1', function(d) {return yScale(d[0].y);})
292 | .attr('x2', function(d) {return xScale(d[1].x);})
293 | .attr('y2', function(d) {return yScale(d[1].y);})
294 | .attr("transform","translate(" + padding.left + "," + padding.top + ")")
295 | .attr('stroke', labelToColor(label));
296 | }
297 | };
298 |
299 | var loadTotalChartAssoc = function(data) {
300 |
301 | $('#total-svg').empty();
302 |
303 | supportData = {}
304 | for(var i = 0; i < data.length; i++) {
305 | elem = data[i];
306 | tmp = elem[2].split(' -> ');
307 | src = tmp[0];
308 | freq = tmp[1].split(', ').concat(src.split(', ')).sort().join(', ');
309 | supportData[freq] = elem[3];
310 | supportData[src] = elem[4];
311 | }
312 | var labels = keys(supportData);
313 | var counts = values(supportData);
314 |
315 | var svg = d3.select("#total-svg");
316 | var width = svg.attr("width");
317 | var height = svg.attr("height") - 30;
318 | var xScale = d3.scale.ordinal()
319 | .domain(d3.range(counts.length))
320 | .rangeRoundBands([0, width]);
321 | var yScale = d3.scale.linear()
322 | .domain([0,d3.max(counts)])
323 | .range([height, 0]);
324 | var rectPadding = 4;
325 | var rects = svg.selectAll(".rect")
326 | .data(counts)
327 | .enter()
328 | .append("rect")
329 | //.attr("class", "MyRect")
330 | //.attr("transform", "translate(" + padding.left + "," + padding.top + ")")
331 | .attr("x", function(d,i){
332 | return xScale(i) + rectPadding/2;
333 | } )
334 | .attr("y",function(d){
335 | return yScale(d);
336 | })
337 | .attr("width", xScale.rangeBand() - rectPadding )
338 | .attr("height", function(d){
339 | return height - yScale(d);
340 | })
341 | .attr("fill", function(d, i) {
342 | return labelToColor(i);
343 | });
344 |
345 | var texts = svg.selectAll(".text")
346 | .data(counts)
347 | .enter()
348 | .append("text")
349 | //.attr("class","MyText")
350 | //.attr("transform","translate(" + padding.left + "," + padding.top + ")")
351 | .attr("x", function(d,i){
352 | return xScale(i) + rectPadding/2;
353 | } )
354 | .attr("y",function(d){
355 | return yScale(d);
356 | })
357 | .attr("dx",function(){
358 | return (xScale.rangeBand() - rectPadding)/2 - 10;
359 | })
360 | .attr("dy", 20)
361 | .text(function(d){
362 | return d;
363 | })
364 | .attr('fill', 'white');
365 |
366 | var texts = svg.selectAll(".label")
367 | .data(labels)
368 | .enter()
369 | .append("text")
370 | //.attr("class","MyText")
371 | //.attr("transform","translate(" + padding.left + "," + padding.top + ")")
372 | .attr("x", function(d,i){
373 | return xScale(i) + rectPadding/2;
374 | } )
375 | .attr("y", height)
376 | .attr("dx",function(d){
377 | var len = d.length * 10;
378 | return (xScale.rangeBand() - rectPadding - len) / 2 ;
379 | })
380 | .attr("dy", 20)
381 | .text(function(d){
382 | return d;
383 | })
384 | .attr('fill', 'black');
385 | }
386 |
387 | var loadDistChartAssoc = function (data) {
388 |
389 | $('#dist-svg').empty();
390 |
391 | var dataDict = {};
392 | var srcSet = {};
393 | var dstSet = {};
394 | for(var i = 0; i < data.length; i++) {
395 | var elem = data[i];
396 | dataDict[elem[2]] = Number.parseFloat(elem[1]);
397 | var res = elem[2].split(' -> ');
398 | srcSet[res[0]] = 0;
399 | dstSet[res[1]] = 1;
400 | }
401 | srcList = keys(srcSet);
402 | dstList = keys(dstSet);
403 | console.log(dataDict);
404 | console.log(srcList);
405 | console.log(dstList);
406 |
407 | points = [];
408 | for(var i = 0; i < srcList.length; i++) {
409 | for(var j = 0; j < dstList.length; j++) {
410 | var k = srcList[i] + ' -> ' + dstList[j];
411 | if(dataDict[k]) {
412 | var conf = dataDict[k];
413 | points.push({x: j, y: i, conf: conf});
414 | }
415 | }
416 | }
417 |
418 | var padding = {left: 50, right: 0, top: 0, bottom: 20};
419 | var maxRadius = 15;
420 | var svg = d3.select('#dist-svg');
421 | var width = svg.attr("width") - padding.left - padding.right;
422 | var height = svg.attr("height") - padding.top - padding.bottom;
423 |
424 | var xScale = d3.scale.ordinal()
425 | .domain(d3.range(dstList.length))
426 | .rangeRoundBands([0, width]);
427 | var yScale = d3.scale.ordinal()
428 | .domain(d3.range(srcList.length))
429 | .rangeRoundBands([0, height]);
430 |
431 | var hLine = svg.selectAll(".line")
432 | .data(srcList)
433 | .enter()
434 | .append("line")
435 | .attr('x1', xScale(0) + xScale.rangeBand() / 2)
436 | .attr('x2', xScale(dstList.length - 1) + xScale.rangeBand() / 2)
437 | .attr('y1', function(d, i) {
438 | return height - yScale(i) - yScale.rangeBand() / 2;
439 | })
440 | .attr('y2', function(d, i) {
441 | return height - yScale(i) - yScale.rangeBand() / 2;
442 | })
443 | .attr("transform","translate(" + padding.left + "," + padding.top + ")")
444 | .attr('stroke', '#ccc')
445 | .attr('stroke-dasharray', '5,5');
446 |
447 | var vLines = svg.selectAll(".line")
448 | .data(dstList)
449 | .enter()
450 | .append("line")
451 | .attr('x1', function(d,i){
452 | return xScale(i) + xScale.rangeBand() / 2;
453 | })
454 | .attr('x2', function(d,i){
455 | return xScale(i) + xScale.rangeBand() / 2;
456 | })
457 | .attr('y1', yScale(0) + yScale.rangeBand() / 2)
458 | .attr('y2', yScale(srcList.length - 1) + yScale.rangeBand() / 2)
459 | .attr("transform","translate(" + padding.left + "," + padding.top + ")")
460 | .attr('stroke', '#ccc')
461 | .attr('stroke-dasharray', '5,5');
462 |
463 | var circles = svg.selectAll('.circle')
464 | .data(points)
465 | .enter()
466 | .append("circle")
467 | .attr('cx', function(d) {
468 | return xScale(d.x) + xScale.rangeBand() / 2;
469 | })
470 | .attr('cy', function(d) {
471 | console.log(d, yScale(d.y), srcList.length);
472 | return height - yScale(d.y) - yScale.rangeBand() / 2;
473 |
474 | })
475 | .attr('r', function(d) {
476 | return d.conf * maxRadius;
477 | })
478 | .attr("transform","translate(" + padding.left + "," + padding.top + ")")
479 | .attr('fill', function(d) {
480 | return labelToColor(d.x + d.y);
481 | });
482 |
483 |
484 | var xTexts = svg.selectAll(".label")
485 | .data(dstList)
486 | .enter()
487 | .append("text")
488 | .attr("x", function(d,i){
489 | return xScale(i) + xScale.rangeBand() / 2;
490 | } )
491 | .attr("y", height)
492 | .attr("dx", -15)
493 | .attr("dy", 0)
494 | .text(function(d){
495 | return d;
496 | })
497 | .attr("transform","translate(" + padding.left + "," + padding.top + ")")
498 | .attr('fill', 'black');
499 |
500 | var yTexts = svg.selectAll(".label")
501 | .data(srcList)
502 | .enter()
503 | .append("text")
504 | .attr("x", 0)
505 | .attr("y", function(d, i) {
506 | return height - yScale(i) - yScale.rangeBand() / 2;
507 | })
508 | .attr("dx", 0)
509 | .attr("dy", 0)
510 | .text(function(d){
511 | return d;
512 | })
513 | .attr("transform","translate(0," + padding.top + ")")
514 | .attr('fill', 'black');
515 |
516 |
517 | }
518 |
519 | getResult();
520 | });
--------------------------------------------------------------------------------
/doc/diag/entire-arch-0.fem:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | D73A4816-68C7-4831-9C71-A30987EF5958
11 | FreeModel_1
12 | FreeModel_1
13 | 1464519823
14 | asus
15 | 1464519823
16 | asus
17 | [ModelOptions]
18 |
19 | [ModelOptions\Free model options]
20 | CaseSensitive=No
21 | DisplayName=Yes
22 | EnableTrans=No
23 | EnableRequirements=No
24 |
25 | [ModelOptions\Free model options\NamingOptionsTemplates]
26 |
27 | [ModelOptions\Free model options\ClssNamingOptions]
28 |
29 | [ModelOptions\Free model options\ClssNamingOptions\FRMPCKG]
30 |
31 | [ModelOptions\Free model options\ClssNamingOptions\FRMPCKG\Name]
32 | Template=
33 | MaxLen=254
34 | Case=M
35 | ValidChar=
36 | InvldChar=
37 | AllValid=Yes
38 | NoAccent=No
39 | DefaultChar=
40 | Script=
41 | ConvTable=
42 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
43 |
44 | [ModelOptions\Free model options\ClssNamingOptions\FRMPCKG\Code]
45 | Template=
46 | MaxLen=254
47 | Case=M
48 | ValidChar=
49 | InvldChar=
50 | AllValid=Yes
51 | NoAccent=No
52 | DefaultChar=
53 | Script=
54 | ConvTable=
55 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
56 |
57 | [ModelOptions\Free model options\ClssNamingOptions\FILO]
58 |
59 | [ModelOptions\Free model options\ClssNamingOptions\FILO\Name]
60 | Template=
61 | MaxLen=254
62 | Case=M
63 | ValidChar=
64 | InvldChar=
65 | AllValid=Yes
66 | NoAccent=No
67 | DefaultChar=
68 | Script=
69 | ConvTable=
70 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
71 |
72 | [ModelOptions\Free model options\ClssNamingOptions\FILO\Code]
73 | Template=
74 | MaxLen=254
75 | Case=M
76 | ValidChar=
77 | InvldChar=
78 | AllValid=Yes
79 | NoAccent=No
80 | DefaultChar=
81 | Script=
82 | ConvTable=
83 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
84 |
85 | [ModelOptions\Free model options\ClssNamingOptions\FRMEOBJ]
86 |
87 | [ModelOptions\Free model options\ClssNamingOptions\FRMEOBJ\Name]
88 | Template=
89 | MaxLen=254
90 | Case=M
91 | ValidChar=
92 | InvldChar=
93 | AllValid=Yes
94 | NoAccent=No
95 | DefaultChar=
96 | Script=
97 | ConvTable=
98 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
99 |
100 | [ModelOptions\Free model options\ClssNamingOptions\FRMEOBJ\Code]
101 | Template=
102 | MaxLen=254
103 | Case=M
104 | ValidChar=
105 | InvldChar=
106 | AllValid=Yes
107 | NoAccent=No
108 | DefaultChar=
109 | Script=
110 | ConvTable=
111 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
112 |
113 | [ModelOptions\Free model options\ClssNamingOptions\FRMELNK]
114 |
115 | [ModelOptions\Free model options\ClssNamingOptions\FRMELNK\Name]
116 | Template=
117 | MaxLen=254
118 | Case=M
119 | ValidChar=
120 | InvldChar=
121 | AllValid=Yes
122 | NoAccent=No
123 | DefaultChar=
124 | Script=
125 | ConvTable=
126 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
127 |
128 | [ModelOptions\Free model options\ClssNamingOptions\FRMELNK\Code]
129 | Template=
130 | MaxLen=254
131 | Case=M
132 | ValidChar=
133 | InvldChar=
134 | AllValid=Yes
135 | NoAccent=No
136 | DefaultChar=
137 | Script=
138 | ConvTable=
139 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
140 |
141 | [ModelOptions\Free model options\ClssNamingOptions\DefaultClass]
142 |
143 | [ModelOptions\Free model options\ClssNamingOptions\DefaultClass\Name]
144 | Template=
145 | MaxLen=254
146 | Case=M
147 | ValidChar=
148 | InvldChar=
149 | AllValid=Yes
150 | NoAccent=No
151 | DefaultChar=
152 | Script=
153 | ConvTable=
154 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
155 |
156 | [ModelOptions\Free model options\ClssNamingOptions\DefaultClass\Code]
157 | Template=
158 | MaxLen=254
159 | Case=M
160 | ValidChar=
161 | InvldChar=
162 | AllValid=Yes
163 | NoAccent=No
164 | DefaultChar=
165 | Script=
166 | ConvTable=
167 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
168 |
169 |
170 | 69272F07-0C28-4600-8120-5E662E697467
171 | Diagram_1
172 | Diagram_1
173 | 1464519823
174 | asus
175 | 1464520106
176 | asus
177 | [DisplayPreferences]
178 |
179 | [DisplayPreferences\FRM]
180 |
181 | [DisplayPreferences\General]
182 | Adjust to text=Yes
183 | Snap Grid=No
184 | Constrain Labels=Yes
185 | Display Grid=No
186 | Show Page Delimiter=Yes
187 | Grid size=0
188 | Graphic unit=2
189 | Window color=255, 255, 255
190 | Background image=
191 | Background mode=8
192 | Watermark image=
193 | Watermark mode=8
194 | Show watermark on screen=No
195 | Gradient mode=0
196 | Gradient end color=255, 255, 255
197 | Show Swimlane=No
198 | SwimlaneVert=Yes
199 | TreeVert=No
200 | CompDark=0
201 |
202 | [DisplayPreferences\Object]
203 | Mode=2
204 | Trunc Length=40
205 | Word Length=40
206 | Word Text=!""#$%&'()*+,-./:;<=>?@[\]^_`{|}~
207 | Shortcut IntIcon=Yes
208 | Shortcut IntLoct=Yes
209 | Shortcut IntFullPath=No
210 | Shortcut IntLastPackage=Yes
211 | Shortcut ExtIcon=Yes
212 | Shortcut ExtLoct=No
213 | Shortcut ExtFullPath=No
214 | Shortcut ExtLastPackage=Yes
215 | Shortcut ExtIncludeModl=Yes
216 | EObjShowStrn=Yes
217 | ExtendedObject.Comment=No
218 | ExtendedObject.IconPicture=No
219 | ExtendedObject_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="<<" Suffix=">>" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Object Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <Separator Name="Separator" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form>
220 | ELnkShowStrn=Yes
221 | ELnkShowName=Yes
222 | ExtendedLink_SymbolLayout=<Form>[CRLF] <Form Name="Center" >[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="<<" Suffix=">>" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Source" >[CRLF] </Form>[CRLF] <Form Name="Destination" >[CRLF] </Form>[CRLF]</Form>
223 | FileObject.Stereotype=No
224 | FileObject.DisplayName=Yes
225 | FileObject.LocationOrName=No
226 | FileObject.IconPicture=No
227 | FileObject.IconMode=Yes
228 | FileObject_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="<<" Suffix=">>" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Location" Attribute="LocationOrName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form>
229 | PckgShowStrn=Yes
230 | Package.Comment=No
231 | Package.IconPicture=No
232 | Package_SymbolLayout=
233 | Display Model Version=Yes
234 |
235 | [DisplayPreferences\Symbol]
236 |
237 | [DisplayPreferences\Symbol\FRMEOBJ]
238 | STRNFont=新宋体,8,N
239 | STRNFont color=0, 0, 0
240 | DISPNAMEFont=新宋体,8,N
241 | DISPNAMEFont color=0, 0, 0
242 | LABLFont=新宋体,8,N
243 | LABLFont color=0, 0, 0
244 | AutoAdjustToText=Yes
245 | Keep aspect=No
246 | Keep center=No
247 | Keep size=No
248 | Width=6000
249 | Height=2000
250 | Brush color=255 255 255
251 | Fill Color=Yes
252 | Brush style=6
253 | Brush bitmap mode=12
254 | Brush gradient mode=64
255 | Brush gradient color=192 192 192
256 | Brush background image=
257 | Custom shape=
258 | Custom text mode=0
259 | Pen=1 0 255 128 128
260 | Shadow color=192 192 192
261 | Shadow=0
262 |
263 | [DisplayPreferences\Symbol\FRMELNK]
264 | CENTERFont=新宋体,8,N
265 | CENTERFont color=0, 0, 0
266 | Line style=1
267 | AutoAdjustToText=Yes
268 | Keep aspect=No
269 | Keep center=No
270 | Keep size=No
271 | Brush color=255 255 255
272 | Fill Color=Yes
273 | Brush style=1
274 | Brush bitmap mode=12
275 | Brush gradient mode=0
276 | Brush gradient color=118 118 118
277 | Brush background image=
278 | Custom shape=
279 | Custom text mode=0
280 | Pen=1 0 128 128 255
281 | Shadow color=192 192 192
282 | Shadow=0
283 |
284 | [DisplayPreferences\Symbol\FILO]
285 | OBJSTRNFont=新宋体,8,N
286 | OBJSTRNFont color=0, 0, 0
287 | DISPNAMEFont=新宋体,8,N
288 | DISPNAMEFont color=0, 0, 0
289 | LCNMFont=新宋体,8,N
290 | LCNMFont color=0, 0, 0
291 | AutoAdjustToText=Yes
292 | Keep aspect=No
293 | Keep center=No
294 | Keep size=No
295 | Width=4800
296 | Height=3600
297 | Brush color=255 255 255
298 | Fill Color=Yes
299 | Brush style=1
300 | Brush bitmap mode=12
301 | Brush gradient mode=0
302 | Brush gradient color=118 118 118
303 | Brush background image=
304 | Custom shape=
305 | Custom text mode=0
306 | Pen=1 0 0 0 255
307 | Shadow color=192 192 192
308 | Shadow=0
309 |
310 | [DisplayPreferences\Symbol\FRMPCKG]
311 | STRNFont=新宋体,8,N
312 | STRNFont color=0, 0, 0
313 | DISPNAMEFont=新宋体,8,N
314 | DISPNAMEFont color=0, 0, 0
315 | LABLFont=新宋体,8,N
316 | LABLFont color=0, 0, 0
317 | AutoAdjustToText=Yes
318 | Keep aspect=No
319 | Keep center=No
320 | Keep size=No
321 | Width=4800
322 | Height=3600
323 | Brush color=255 255 192
324 | Fill Color=Yes
325 | Brush style=6
326 | Brush bitmap mode=12
327 | Brush gradient mode=65
328 | Brush gradient color=255 255 255
329 | Brush background image=
330 | Custom shape=
331 | Custom text mode=0
332 | Pen=1 0 178 178 178
333 | Shadow color=192 192 192
334 | Shadow=0
335 |
336 | [DisplayPreferences\Symbol\USRDEPD]
337 | OBJXSTRFont=新宋体,8,N
338 | OBJXSTRFont color=0, 0, 0
339 | Line style=1
340 | AutoAdjustToText=Yes
341 | Keep aspect=No
342 | Keep center=No
343 | Keep size=No
344 | Brush color=255 255 255
345 | Fill Color=Yes
346 | Brush style=1
347 | Brush bitmap mode=12
348 | Brush gradient mode=0
349 | Brush gradient color=118 118 118
350 | Brush background image=
351 | Custom shape=
352 | Custom text mode=0
353 | Pen=2 0 128 128 255
354 | Shadow color=192 192 192
355 | Shadow=0
356 |
357 | [DisplayPreferences\Symbol\Free Symbol]
358 | Free TextFont=新宋体,8,N
359 | Free TextFont color=0, 0, 0
360 | Line style=0
361 | AutoAdjustToText=Yes
362 | Keep aspect=No
363 | Keep center=No
364 | Keep size=No
365 | Brush color=255 255 255
366 | Fill Color=Yes
367 | Brush style=1
368 | Brush bitmap mode=12
369 | Brush gradient mode=0
370 | Brush gradient color=118 118 118
371 | Brush background image=
372 | Custom shape=
373 | Custom text mode=0
374 | Pen=1 0 0 0 255
375 | Shadow color=192 192 192
376 | Shadow=0
377 | (8268, 11693)
378 | ((315,354), (433,354))
379 | 1
380 | 15
381 |
382 |
383 | 1464520073
384 | 1464520096
385 | ((-23820,18101), (-7546,6927))
386 | 4130
387 | 0
388 | 0
389 | 3
390 | 16777215
391 | 12632256
392 | 新宋体,8,N
393 | 1
394 |
395 |
396 | 1464519970
397 | 1464520035
398 | ((-11520,9900), (-11055,14925))
399 | ((-11250,9900),(-11325,14925))
400 | 0
401 | 1
402 | 0
403 | 12632256
404 | 新宋体,8,N
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 | 1464519972
414 | 1464520037
415 | ((-19875,9525), (-11700,15075))
416 | ((-11700,9525),(-19875,15075))
417 | 0
418 | 1
419 | 0
420 | 12632256
421 | 新宋体,8,N
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 | 1464519975
431 | 1464520032
432 | ((-8850,9260), (4275,9716))
433 | ((-8850,9450),(4275,9525))
434 | 0
435 | 1
436 | 0
437 | 12632256
438 | 新宋体,8,N
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 | 1464519979
448 | 1464520038
449 | ((-11625,-3675), (-11175,8775))
450 | ((-11400,-3675),(-11400,8775))
451 | 0
452 | 1
453 | 0
454 | 12632256
455 | 新宋体,8,N
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 | 1464519982
465 | 1464520039
466 | ((-20325,-3600), (-19875,8550))
467 | ((-20100,-3600),(-20100,8550))
468 | 0
469 | 1
470 | 0
471 | 12632256
472 | 新宋体,8,N
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 | 1464519983
482 | 1464520041
483 | ((-9150,-4350), (4125,8775))
484 | ((-9150,-4350),(4125,8775))
485 | 0
486 | 1
487 | 0
488 | 12632256
489 | 新宋体,8,N
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 | Web
499 | 1464519831
500 | 1464519887
501 | ((-14400,11175), (-7950,7650))
502 | 4130
503 | 0
504 | 0
505 | 16777215
506 | 12632256
507 | 新宋体,8,N
508 |
509 |
510 | DB
511 | 1464519889
512 | 1464519896
513 | ((-14550,16838), (-8100,13313))
514 | 4130
515 | 0
516 | 0
517 | 16777215
518 | 12632256
519 | 新宋体,8,N
520 |
521 |
522 | 邮件服务
523 | 1464519898
524 | 1464520005
525 | ((-23100,16913), (-16650,13388))
526 | 4130
527 | 0
528 | 0
529 | 16777215
530 | 12632256
531 | 新宋体,8,N
532 |
533 |
534 | CDN
535 | 1464519905
536 | 1464519913
537 | ((-23175,11213), (-16725,7688))
538 | 4130
539 | 0
540 | 0
541 | 16777215
542 | 12632256
543 | 新宋体,8,N
544 |
545 |
546 | RMP
547 | 1464519913
548 | 1464519938
549 | ((-1199,16763), (12299,7727))
550 | 4130
551 | 0
552 | 0
553 | 16777215
554 | 12632256
555 | 新宋体,8,N
556 | 1
557 |
558 |
559 | 浏览器
560 | 1464519923
561 | 1464519999
562 | ((-22949,-2587), (-8025,-6113))
563 | 4130
564 | 0
565 | 0
566 | 16777215
567 | 12632256
568 | 新宋体,8,N
569 | 1
570 |
571 |
572 | 数据挖掘平台
573 | 1464520106
574 | 1464520125
575 | ((-23847,18341), (-19048,19706))
576 | 4130
577 | 0
578 | 16777215
579 | 16777215
580 | 12632256
581 | 新宋体,8,N
582 | 1
583 |
584 |
585 |
586 |
587 |
588 |
589 |
590 |
591 |
592 |
593 |
594 |
--------------------------------------------------------------------------------
/req_handlers.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from flask import request, make_response
4 | import re
5 | import os
6 | import config
7 | import urllib2
8 | import time
9 | from threading import Thread
10 | import dm
11 |
12 | import sys
13 | reload(sys)
14 | sys.setdefaultencoding('utf-8')
15 |
16 | import json
17 | json.stringify = json.dumps
18 | json.parse = json.loads
19 |
20 | def index():
21 | return 'Hello, Flask!'
22 |
23 | def isAssoc(algo):
24 | return algo in ['apriori']
25 |
26 | def isClassify(algo):
27 | return algo in ['naive_bayes', 'knn', 'svm']
28 |
29 | def isCluster(algo):
30 | return algo in ['kmeans', 'kmedoids']
31 |
32 | """
33 | 参数:
34 | cols:列名称的列表
35 | rows:记录的偏移(可选)及数量
36 | algo:所使用的算法
37 | args:算法所需的参数,格式为json
38 | """
39 | def mining(uid, token, proj, rsrc):
40 |
41 | res = make_response()
42 | res.headers['Content-Type'] = "application/json"
43 |
44 | #获取参数
45 | for e in [token, proj, rsrc]:
46 | if not re.match(r'^\w+$', e):
47 | res.data = json.stringify({'succ': False, 'msg': 'Rsrc invalid!'})
48 | return res
49 |
50 | # title
51 | title = request.form.get('title')
52 | if not title:
53 | res.data = json.stringify({'succ': False, 'msg': 'No title!'})
54 | return res
55 |
56 | # cols=["col0","col1","col2", ...]
57 | cols = request.form.get('cols')
58 | if cols:
59 | cols = json.parse(cols)
60 | assert isinstance(cols, list)
61 | else:
62 | cols = []
63 |
64 | # start
65 | start = request.form.get('start')
66 | if start:
67 | start = int(start)
68 | else:
69 | start = 0
70 |
71 | # count
72 | count = request.form.get('count')
73 | if count:
74 | count = int(count)
75 | end = start + count
76 | else:
77 | end = None
78 |
79 | algo = request.form.get('algo')
80 |
81 | args = request.form.get('args')
82 | print args
83 | if args:
84 | args = json.parse(args)
85 | assert isinstance(args, dict)
86 | else:
87 | args = {}
88 | # TODO: filter args
89 |
90 | context = {
91 | "user": uid,
92 | "title": title,
93 | "rsrc": token + '/' + proj + '/' + rsrc,
94 | "cols": cols,
95 | "start": start,
96 | "end": end,
97 | "algo": algo,
98 | "args": args,
99 | }
100 |
101 | if isClassify(algo):
102 | # predictStart
103 | predictStart = request.form.get('predictStart')
104 | if predictStart:
105 | predictStart = int(predictStart)
106 | else:
107 | predictStart = 0
108 |
109 | # predictCount
110 | predictCount = request.form.get('predictCount')
111 | if predictCount:
112 | predictCount = int(predictCount)
113 | predictEnd = predictStart + predictCount
114 | else:
115 | predictEnd = None
116 |
117 | label = request.form.get('label')
118 | if label is None: label = ""
119 | if not re.match(r'^\w+$', label):
120 | return json.stringify({'succ': False, 'msg': 'Label invalid!'})
121 |
122 | context['predictStart'] = predictStart
123 | context['predictEnd'] = predictEnd
124 | context['label'] = label
125 |
126 | if not isAssoc(algo):
127 | absence = request.form.get('absence')
128 | fillval = request.form.get('fillval')
129 | if fillval is None: fillval = 0
130 | formal = request.form.get('formal')
131 | distinct = request.form.get('distinct') == 'true'
132 |
133 | context['absence'] = absence
134 | context['fillval'] = fillval
135 | context['formal'] = formal
136 | context['distinct'] = distinct
137 |
138 |
139 |
140 | # 调用具体算法
141 | funcDict = {
142 | "kmeans": kmeans,
143 | "kmedoids": kmedoids,
144 | "apriori": apriori,
145 | "naive_bayes": classify,
146 | "knn": classify,
147 | "svm": classify
148 | }
149 | func = funcDict.get(algo)
150 | if not func:
151 | res.data = json.stringify({'succ': False, 'msg': 'Unknown algo!'})
152 | return res
153 |
154 | Thread(target=func, args=(context,)).start();
155 |
156 | res.data = json.stringify({'succ': True, 'msg': 'Done...'})
157 | return res
158 |
159 | def preprocess(data, context):
160 |
161 | absence = context['absence']
162 | if absence == 'rm':
163 | data = dm.removeAbsence(data)
164 | elif absence == 'val':
165 | data = dm.fillAbsenceWithVal(data, context['fillval'])
166 | elif absence == 'avg':
167 | data = dm.fillAbsenceWithAvg(data)
168 |
169 | formal = context['formal']
170 | if formal == 'maxmin':
171 | data = dm.maxMinRestrict(data)
172 | elif formal == 'zscore':
173 | data = dm.zScoreRestrict(data)
174 | elif formal == 'demical':
175 | data = dm.demicalRestrict(data)
176 |
177 | return data
178 |
179 | def apriori(context):
180 | rawData = getDataFromSvr(context['rsrc'])
181 | _, data = processData(rawData, context['start'], \
182 | context['end'], context['cols'])
183 | dataList = convertDataToArr(data)
184 |
185 | rawRes = dm.apriori(dataList, **context['args'])
186 |
187 | conn = config.getConn()
188 | cursor = conn.cursor()
189 | hid = dbAddHistory(cursor, context, 'assoc')
190 | result = []
191 | count = 0
192 | for row in rawRes:
193 | v = "{0} -> {1}".format(
194 | ', '.join(row[0]),
195 | ', '.join(row[1])
196 | )
197 | result.append((hid, count, row[2], v, row[3], row[4]))
198 | count += 1
199 | dbWriteBackAssoc(cursor, result)
200 | dbAddMessage(cursor, context, hid)
201 | try: sendMessageByEmail(cursor, context, hid)
202 | except Exception: pass
203 |
204 | conn.commit()
205 | cursor.close()
206 | conn.close()
207 | return json.stringify({'succ': True, 'msg': 'Done...'})
208 |
209 | def kmedoids(context):
210 | rawData = getDataFromSvr(context['rsrc'])
211 | if(context['distinct']):
212 | rawData = dm.distinct(rawData)
213 | idList, data = processData(rawData, context['start'], \
214 | context['end'], context['cols'])
215 | dataList = convertDataToArr(data)
216 | dataList = preprocess(dataList, context)
217 |
218 | _, _, rawRes = dm.kmedoids(dataList, **context['args'])
219 |
220 | conn = config.getConn()
221 | cursor = conn.cursor()
222 | hid = dbAddHistory(cursor, context, 'cluster')
223 | result = []
224 | clusterId = 0
225 | for medoid in rawRes.keys():
226 | for i in rawRes[medoid]:
227 | result.append((hid, idList[i], clusterId,
228 | json.stringify(dataList[i])))
229 | clusterId += 1
230 |
231 | dbWriteBack(cursor, result)
232 | dbAddMessage(cursor, context, hid)
233 | try: sendMessageByEmail(cursor, context, hid)
234 | except Exception: pass
235 |
236 | conn.commit()
237 | cursor.close()
238 | conn.close()
239 | return json.stringify({'succ': True, 'msg': 'Done...'})
240 |
241 | def kmeans(context):
242 | rawData = getDataFromSvr(context['rsrc'])
243 | if(context['distinct']):
244 | rawData = dm.distinct(rawData)
245 | idList, data = processData(rawData, context['start'], \
246 | context['end'], context['cols'])
247 | dataList = convertDataToArr(data)
248 | dataList = preprocess(dataList, context)
249 |
250 | from sklearn.cluster import KMeans
251 | clf = KMeans(**context['args'])
252 | clf.fit(dataList)
253 |
254 | conn = config.getConn()
255 | cursor = conn.cursor()
256 | hid = dbAddHistory(cursor, context, 'cluster')
257 | result = []
258 | for i in xrange(len(clf.labels_)):
259 | result.append((hid, idList[i], clf.labels_[i],
260 | json.stringify(data[i])))
261 |
262 | dbWriteBack(cursor, result)
263 | dbAddMessage(cursor, context, hid)
264 | try: sendMessageByEmail(cursor, context, hid)
265 | except Exception: pass
266 |
267 | conn.commit()
268 | cursor.close()
269 | conn.close()
270 | return json.stringify({'succ': True, 'msg': 'Done...'})
271 |
272 | def classify(context):
273 |
274 | from sklearn.neighbors import KNeighborsClassifier
275 | from sklearn.naive_bayes import MultinomialNB
276 | from sklearn.svm import SVC
277 |
278 | label = context['label']
279 | algo = context['algo']
280 | if algo == 'svm':
281 | classifier = SVC
282 | elif algo == 'knn':
283 | classifier = KNeighborsClassifier
284 | elif algo == 'naive_bayes':
285 | classifier = MultinomialNB
286 | else:
287 | assert False
288 | args = context['args']
289 | for k in args:
290 | if isinstance(args[k], unicode):
291 | args[k] = str(args[k])
292 |
293 | rawData = getDataFromSvr(context['rsrc'])
294 | if(context['distinct']):
295 | rawData = dm.distinct(rawData)
296 | labelList, train = getTrainingSet(rawData, label, context['start'], \
297 | context['end'], context['cols'])
298 | trainList = convertDataToArr(train)
299 | trainList = preprocess(trainList, context)
300 | idList, predict = getPredictSet(rawData, context['predictStart'], \
301 | context['predictEnd'], context['cols'])
302 | predictList = convertDataToArr(predict)
303 | predictList = preprocess(predictList, context)
304 |
305 | clf = classifier(**args)
306 | clf.fit(trainList, labelList)
307 | rawRes = clf.predict(predictList)
308 |
309 | conn = config.getConn()
310 | cursor = conn.cursor()
311 | id = dbAddHistory(cursor, context, 'classify')
312 |
313 | result = []
314 | for i in xrange(len(rawRes)):
315 | result.append((id, idList[i], rawRes[i], json.stringify(predict[i])))
316 |
317 | dbWriteBack(cursor, result)
318 | dbAddMessage(cursor, context, id)
319 | try: sendMessageByEmail(cursor, context, hid)
320 | except Exception: pass
321 |
322 | conn.commit()
323 | cursor.close()
324 | conn.close()
325 | return json.stringify({'succ': True, 'msg': 'Done...'})
326 |
327 | def dbAddMessage(cursor, context, hid):
328 | content = "您提交的任务已完成,资源:{0},ID:{1}。".format(context['rsrc'], hid);
329 | sql = 'insert into message (userid, content, tm) values (%s, %s, null)'
330 | cursor.execute(sql, (context['user'], content))
331 |
332 | def dbAddHistory(cursor, context, type):
333 | sql = 'insert into history (userid, title, rsrc, tp, tm) values (%s, %s, %s, %s, null)'
334 | cursor.execute(sql, (context['user'], context['title'], context['rsrc'], type))
335 | return cursor.lastrowid
336 |
337 | def dbWriteBack(cursor, result):
338 | sql = "insert into result (hid, id, res1, res2) values (%s,%s,%s,%s)"
339 | cursor.executemany(sql, result)
340 |
341 | def dbWriteBackAssoc(cursor, result):
342 | sql = "insert into result (hid, id, res1, res2, res3, res4) values (%s,%s,%s,%s,%s,%s)"
343 | cursor.executemany(sql, result)
344 |
345 | def getDataFromSvr(rsrc):
346 | url = config.rmp + '/Entity/' + rsrc + '/'
347 | jsonStr = urllib2.urlopen(urllib2.Request(url)).read().decode('utf-8')
348 | return json.parse(jsonStr)[rsrc.split('/')[-1]]
349 |
350 | def convertData(data, start = 0, end = None, cols = [], label = None):
351 | """
352 | 将对象数组转化为二维数组,
353 | 将id单独拿出来存为数组,
354 | 如有标签将其去除,
355 | 最后将数组切片。
356 | """
357 |
358 | idList = []
359 | dataList = []
360 | labelList = []
361 | for elem in data:
362 | elemId = elem['id']
363 | idList.append(elemId)
364 | del elem['id']
365 |
366 | if(label):
367 | elemLabel = elem[label]
368 | labelList.append(elemLabel)
369 | del elem[label]
370 |
371 | row = []
372 | for k, v in elem.items():
373 | if (v != None and v != "") and \
374 | (len(cols) == 0 or k in cols):
375 | row.append(v)
376 | dataList.append(row)
377 |
378 | elem['id'] = elemId
379 | if(label): elem[label] = elemLabel
380 |
381 | return idList[start:end], \
382 | dataList[start:end], labelList[start:end]
383 |
384 | def processData(rawData, start = 0, end = None, cols = []):
385 | data = rawData[start:end]
386 |
387 | idList = []
388 | for i in xrange(len(data)):
389 | elem = dict(data[i])
390 | idList.append(elem['id'])
391 | del elem['id']
392 | for k, v in elem.items():
393 | if len(cols) != 0 and k not in cols:
394 | del elem[k]
395 | data[i] = elem
396 | return idList, data
397 |
398 | getPredictSet = processData
399 |
400 | def getTrainingSet(rawData, label, start = 0, end = None, cols = []):
401 | data = rawData[start:end]
402 | labelList = []
403 | for i in xrange(len(data)):
404 | elem = dict(data[i])
405 | del elem['id']
406 | labelList.append(elem[label])
407 | for k, v in elem.items():
408 | if len(cols) != 0 and k not in cols:
409 | del elem[k]
410 | data[i] = elem
411 | return labelList, data
412 |
413 | def convertDataToArr(data):
414 | dataList = []
415 | for elem in data:
416 | row = []
417 | for v in elem.values():
418 | row.append(v)
419 | dataList.append(row)
420 | return dataList
421 |
422 | def getData(context):
423 | rawData = getDataFromSvr(context['rsrc'])
424 |
425 | cols = context['cols']
426 | start = context['start']
427 | end = context['end']
428 | idList, dataList, _ = convertData(rawData, start, end, cols)
429 |
430 | return idList, dataList
431 |
432 | def getDataWithLabel(context):
433 | rawData = getDataFromSvr(context['rsrc'])
434 |
435 | cols = context['cols']
436 | start = context['start']
437 | end = context['end']
438 | predictStart = context['predictStart']
439 | predictEnd = context['predictEnd']
440 | label = context['label']
441 |
442 | # 训练集
443 | _, dataList, labelList = convertData(rawData, start, end, cols, label)
444 |
445 | # 测试集
446 | idList, predictList, _ = convertData(rawData, predictStart, predictEnd, cols, label)
447 |
448 | return dataList, labelList, idList, predictList
449 |
450 | def getHistory(uid):
451 | return getHistoryById(uid, 0)
452 |
453 | # id=0时为全部
454 | def dbGetHistory(cur, uid, id):
455 | sql = "select id,rsrc,tp,tm,title from history where 1=1"
456 | args = []
457 | if id != 0:
458 | sql += ' and id=%s'
459 | args.append(id)
460 | if uid != 0:
461 | sql += ' and userid=%s'
462 | args.append(uid)
463 | cur.execute(sql, tuple(args))
464 | result = []
465 | for row in cur.fetchall():
466 | obj = {
467 | "id": row[0],
468 | "rsrc": row[1],
469 | "type": row[2],
470 | "time": str(row[3]),
471 | "title": row[4]
472 | }
473 | result.append(obj)
474 | return result
475 |
476 | # id=0时为全部
477 | def getHistoryById(uid, id):
478 | conn = config.getConn()
479 | cur = conn.cursor()
480 | result = dbGetHistory(cur, uid, id)
481 | cur.close()
482 | conn.close()
483 | res = make_response(json.stringify({"succ": True, "data": result}))
484 | res.headers["Content-Type"] = "application/json"
485 | return res
486 |
487 | def dbGetResult(cur, id):
488 | sql = "select id,res1,res2,res3,res4 from result where hid=%s"
489 | cur.execute(sql, (id,))
490 | result = cur.fetchall()
491 | return result
492 |
493 | def getResultById(id):
494 | conn = config.getConn()
495 | cur = conn.cursor()
496 | result = dbGetResult(cur, id)
497 | cur.close()
498 | conn.close()
499 | res = make_response(json.stringify({"succ": True, "data": result}))
500 | return res
501 |
502 | def csvForm(s):
503 | s = str(s)
504 | if ',' in s:
505 | s = '"' + s.replace('"', '""') + '"'
506 | return s
507 |
508 | def generateCsvAssoc(data):
509 | from cStringIO import StringIO
510 | buffer = StringIO()
511 | headLine = ['rule', 'conf', 'frequent support', 'src support']
512 | buffer.write(','.join(headLine))
513 | buffer.write('\n')
514 |
515 | for row in data:
516 | line = map(csvForm, [row[2], row[1], row[3], row[4]])
517 | buffer.write(','.join(line))
518 | buffer.write('\n')
519 |
520 | return buffer.getvalue()
521 |
522 | def generateCsvOther(data):
523 | data = [list(row) for row in data]
524 | for row in data:
525 | row[2] = json.parse(row[2])
526 | attrs = data[0][2].keys()
527 |
528 | from cStringIO import StringIO
529 | buffer = StringIO()
530 |
531 | headLine = []
532 | headLine.append('id')
533 | for k in attrs: headLine.append(k)
534 | headLine.append('label')
535 | buffer.write(','.join(headLine))
536 | buffer.write('\n')
537 |
538 | for row in data:
539 | line = []
540 | line.append(str(row[0]))
541 | for k in attrs: line.append(str(row[2][k]))
542 | line.append(str(row[1]))
543 | line = map(csvForm, line)
544 | buffer.write(','.join(line))
545 | buffer.write('\n')
546 |
547 | return buffer.getvalue()
548 |
549 | def getResultCsv(id):
550 | conn = config.getConn()
551 | cur = conn.cursor()
552 | history = dbGetHistory(cur, 0, id)
553 | data = dbGetResult(cur, id)
554 | cur.close()
555 | conn.close()
556 |
557 | if len(history) == 0:
558 | assert False
559 | history = history[0]
560 |
561 | if history['type'] == 'assoc':
562 | result = generateCsvAssoc(data)
563 | else:
564 | result = generateCsvOther(data)
565 | res = make_response(result)
566 | res.headers["Content-Type"] = "application/csv;charset=utf-8"
567 | res.headers["Content-Disposition"] = "attachment; filename=" + str(id) + ".csv"
568 | return res
569 |
570 | # isread=-1时为全部
571 | def getMessage(uid, isread):
572 | conn = config.getConn()
573 | cur = conn.cursor()
574 | sql = "select id,content,tm,isread from message where userid=%s"
575 | if isread == 1:
576 | sql += " and isread=1"
577 | elif isread == 0:
578 | sql += " and isread=0"
579 | sql += " order by id desc"
580 | cur.execute(sql, (uid,))
581 | result = cur.fetchall()
582 | cur.close()
583 | conn.close()
584 | newResult = []
585 | for row in result:
586 | obj = {
587 | "id": row[0],
588 | "content": row[1],
589 | "tm": str(row[2]),
590 | "isread": 1 if row[3] else 0
591 | }
592 | newResult.append(obj)
593 | return make_response(json.stringify({"succ": True, "data": newResult}))
594 |
595 | def getMessageUnread(uid):
596 | return getMessage(uid, 0)
597 |
598 | def getMessageAll(uid):
599 | return getMessage(uid, -1)
600 |
601 | # id=0 为全部
602 | def markMessage(uid, id):
603 | conn = config.getConn()
604 | cur = conn.cursor()
605 | sql = "update message set isread=1 where userid=%s"
606 | if id != 0:
607 | sql += " and id=" + str(id)
608 | cur.execute(sql, (uid,))
609 | conn.commit()
610 | cur.close()
611 | conn.close()
612 | return make_response(json.stringify({"succ": True}))
613 |
614 | def markMessageAll(uid):
615 | return markMessage(uid, 0)
616 |
617 | def notify(uid):
618 | conn = config.getConn()
619 | cur = conn.cursor()
620 | sql = "select count(*) from message where userid=%s and isread=0"
621 | cur.execute(sql, (uid,))
622 | num = cur.fetchall()[0][0]
623 | cur.close()
624 | conn.close()
625 | return make_response(json.stringify({"succ": True, "unread": num}))
626 |
627 | def sendEmail(sender, reciver, subject, content, type='plain'):
628 | import smtplib
629 | from email.mime.text import MIMEText
630 |
631 | msg = MIMEText(content, type, 'utf-8')
632 | msg['Subject'] = subject
633 | msg['From'] = sender
634 | msg['To'] = reciver
635 |
636 | smtp = smtplib.SMTP()
637 | smtp.connect(config.smtp['server'])
638 | smtp.starttls()
639 | smtp.login(config.smtp['un'], config.smtp['authcode'])
640 | smtp.sendmail(config.smtp['un'], reciver, msg.as_string())
641 | smtp.quit()
642 |
643 | def setEmail(uid):
644 | email = request.form.get('email')
645 | if email is None: email = ""
646 | if not re.match(r'^[\w\-\.]+?@(\w+?\.)+?\w{2,4}$', email):
647 | return make_response(json.stringify({"succ": False, "msg": "Email format error!"}))
648 | conn = config.getConn()
649 | cur = conn.cursor()
650 | sql = "replace into email (userid, email) values (%s,%s)"
651 | cur.execute(sql, (uid, email))
652 | conn.commit()
653 | cur.close()
654 | conn.close()
655 | return make_response(json.stringify({"succ": True}))
656 |
657 | def dbGetEmail(cur, uid):
658 | sql = "select email from email where userid=%s"
659 | cur.execute(sql, (uid,))
660 | res = cur.fetchall()
661 | if len(res) == 0:
662 | email = ""
663 | else:
664 | email = res[0][0]
665 | return email
666 |
667 | def getEmail(uid):
668 | conn = config.getConn()
669 | cur = conn.cursor()
670 | email = dbGetEmail(cur, uid)
671 | conn.commit()
672 | cur.close()
673 | conn.close()
674 | return make_response(json.stringify({"succ": True, "data": email}))
675 |
676 | def sendMessageByEmail(cur, context, hid):
677 | email = dbGetEmail(cur, context['user'])
678 | if not email: return
679 | subject = "您提交的任务已完成,资源:{0},ID:{1}。".format(context['rsrc'], hid);
680 | url = os.path.join(config.host, 'history.html#' + str(hid)).replace('\\', '/')
681 | content = '点击这里访问。'
682 | sendEmail('test@rmp.com', email, subject, content, 'html')
--------------------------------------------------------------------------------
/doc/diag/traditional-mvc-0.fem:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | FF765B56-0DF7-40A7-8680-AE8CE4CDFDB5
11 | FreeModel_1
12 | FreeModel_1
13 | 1464181320
14 | asus
15 | 1464181320
16 | asus
17 | [ModelOptions]
18 |
19 | [ModelOptions\Free model options]
20 | CaseSensitive=No
21 | DisplayName=Yes
22 | EnableTrans=No
23 | EnableRequirements=No
24 |
25 | [ModelOptions\Free model options\NamingOptionsTemplates]
26 |
27 | [ModelOptions\Free model options\ClssNamingOptions]
28 |
29 | [ModelOptions\Free model options\ClssNamingOptions\FRMPCKG]
30 |
31 | [ModelOptions\Free model options\ClssNamingOptions\FRMPCKG\Name]
32 | Template=
33 | MaxLen=254
34 | Case=M
35 | ValidChar=
36 | InvldChar=
37 | AllValid=Yes
38 | NoAccent=No
39 | DefaultChar=
40 | Script=
41 | ConvTable=
42 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
43 |
44 | [ModelOptions\Free model options\ClssNamingOptions\FRMPCKG\Code]
45 | Template=
46 | MaxLen=254
47 | Case=M
48 | ValidChar=
49 | InvldChar=
50 | AllValid=Yes
51 | NoAccent=No
52 | DefaultChar=
53 | Script=
54 | ConvTable=
55 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
56 |
57 | [ModelOptions\Free model options\ClssNamingOptions\FILO]
58 |
59 | [ModelOptions\Free model options\ClssNamingOptions\FILO\Name]
60 | Template=
61 | MaxLen=254
62 | Case=M
63 | ValidChar=
64 | InvldChar=
65 | AllValid=Yes
66 | NoAccent=No
67 | DefaultChar=
68 | Script=
69 | ConvTable=
70 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
71 |
72 | [ModelOptions\Free model options\ClssNamingOptions\FILO\Code]
73 | Template=
74 | MaxLen=254
75 | Case=M
76 | ValidChar=
77 | InvldChar=
78 | AllValid=Yes
79 | NoAccent=No
80 | DefaultChar=
81 | Script=
82 | ConvTable=
83 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
84 |
85 | [ModelOptions\Free model options\ClssNamingOptions\FRMEOBJ]
86 |
87 | [ModelOptions\Free model options\ClssNamingOptions\FRMEOBJ\Name]
88 | Template=
89 | MaxLen=254
90 | Case=M
91 | ValidChar=
92 | InvldChar=
93 | AllValid=Yes
94 | NoAccent=No
95 | DefaultChar=
96 | Script=
97 | ConvTable=
98 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
99 |
100 | [ModelOptions\Free model options\ClssNamingOptions\FRMEOBJ\Code]
101 | Template=
102 | MaxLen=254
103 | Case=M
104 | ValidChar=
105 | InvldChar=
106 | AllValid=Yes
107 | NoAccent=No
108 | DefaultChar=
109 | Script=
110 | ConvTable=
111 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
112 |
113 | [ModelOptions\Free model options\ClssNamingOptions\FRMELNK]
114 |
115 | [ModelOptions\Free model options\ClssNamingOptions\FRMELNK\Name]
116 | Template=
117 | MaxLen=254
118 | Case=M
119 | ValidChar=
120 | InvldChar=
121 | AllValid=Yes
122 | NoAccent=No
123 | DefaultChar=
124 | Script=
125 | ConvTable=
126 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
127 |
128 | [ModelOptions\Free model options\ClssNamingOptions\FRMELNK\Code]
129 | Template=
130 | MaxLen=254
131 | Case=M
132 | ValidChar=
133 | InvldChar=
134 | AllValid=Yes
135 | NoAccent=No
136 | DefaultChar=
137 | Script=
138 | ConvTable=
139 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
140 |
141 | [ModelOptions\Free model options\ClssNamingOptions\DefaultClass]
142 |
143 | [ModelOptions\Free model options\ClssNamingOptions\DefaultClass\Name]
144 | Template=
145 | MaxLen=254
146 | Case=M
147 | ValidChar=
148 | InvldChar=
149 | AllValid=Yes
150 | NoAccent=No
151 | DefaultChar=
152 | Script=
153 | ConvTable=
154 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
155 |
156 | [ModelOptions\Free model options\ClssNamingOptions\DefaultClass\Code]
157 | Template=
158 | MaxLen=254
159 | Case=M
160 | ValidChar=
161 | InvldChar=
162 | AllValid=Yes
163 | NoAccent=No
164 | DefaultChar=
165 | Script=
166 | ConvTable=
167 | ConvTablePath=%_HOME%\Resource Files\Conversion Tables
168 |
169 |
170 | 1D1278C5-DEBC-4663-95A5-244C785AC6B7
171 | Diagram_1
172 | Diagram_1
173 | 1464181321
174 | asus
175 | 1464181878
176 | asus
177 | [DisplayPreferences]
178 |
179 | [DisplayPreferences\FRM]
180 |
181 | [DisplayPreferences\General]
182 | Adjust to text=Yes
183 | Snap Grid=No
184 | Constrain Labels=Yes
185 | Display Grid=No
186 | Show Page Delimiter=Yes
187 | Grid size=0
188 | Graphic unit=2
189 | Window color=255, 255, 255
190 | Background image=
191 | Background mode=8
192 | Watermark image=
193 | Watermark mode=8
194 | Show watermark on screen=No
195 | Gradient mode=0
196 | Gradient end color=255, 255, 255
197 | Show Swimlane=No
198 | SwimlaneVert=Yes
199 | TreeVert=No
200 | CompDark=0
201 |
202 | [DisplayPreferences\Object]
203 | Mode=2
204 | Trunc Length=40
205 | Word Length=40
206 | Word Text=!""#$%&'()*+,-./:;<=>?@[\]^_`{|}~
207 | Shortcut IntIcon=Yes
208 | Shortcut IntLoct=Yes
209 | Shortcut IntFullPath=No
210 | Shortcut IntLastPackage=Yes
211 | Shortcut ExtIcon=Yes
212 | Shortcut ExtLoct=No
213 | Shortcut ExtFullPath=No
214 | Shortcut ExtLastPackage=Yes
215 | Shortcut ExtIncludeModl=Yes
216 | EObjShowStrn=Yes
217 | ExtendedObject.Comment=No
218 | ExtendedObject.IconPicture=No
219 | ExtendedObject_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="<<" Suffix=">>" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Object Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF] <Separator Name="Separator" />[CRLF] <StandardAttribute Name="Comment" Attribute="Comment" Prefix="" Suffix="" Alignment="LEFT" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form>
220 | ELnkShowStrn=Yes
221 | ELnkShowName=Yes
222 | ExtendedLink_SymbolLayout=<Form>[CRLF] <Form Name="Center" >[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="<<" Suffix=">>" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Caption="" Mandatory="No" />[CRLF] </Form>[CRLF] <Form Name="Source" >[CRLF] </Form>[CRLF] <Form Name="Destination" >[CRLF] </Form>[CRLF]</Form>
223 | FileObject.Stereotype=No
224 | FileObject.DisplayName=Yes
225 | FileObject.LocationOrName=No
226 | FileObject.IconPicture=No
227 | FileObject.IconMode=Yes
228 | FileObject_SymbolLayout=<Form>[CRLF] <StandardAttribute Name="Stereotype" Attribute="Stereotype" Prefix="<<" Suffix=">>" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <ExclusiveChoice Name="Exclusive Choice" Mandatory="Yes" Display="HorizontalRadios" >[CRLF] <StandardAttribute Name="Name" Attribute="DisplayName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] <StandardAttribute Name="Location" Attribute="LocationOrName" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="No" />[CRLF] </ExclusiveChoice>[CRLF] <StandardAttribute Name="Icon" Attribute="IconPicture" Prefix="" Suffix="" Alignment="CNTR" Caption="" Mandatory="Yes" />[CRLF]</Form>
229 | PckgShowStrn=Yes
230 | Package.Comment=No
231 | Package.IconPicture=No
232 | Package_SymbolLayout=
233 | Display Model Version=Yes
234 |
235 | [DisplayPreferences\Symbol]
236 |
237 | [DisplayPreferences\Symbol\FRMEOBJ]
238 | STRNFont=新宋体,8,N
239 | STRNFont color=0, 0, 0
240 | DISPNAMEFont=新宋体,8,N
241 | DISPNAMEFont color=0, 0, 0
242 | LABLFont=新宋体,8,N
243 | LABLFont color=0, 0, 0
244 | AutoAdjustToText=Yes
245 | Keep aspect=No
246 | Keep center=No
247 | Keep size=No
248 | Width=6000
249 | Height=2000
250 | Brush color=255 255 255
251 | Fill Color=Yes
252 | Brush style=6
253 | Brush bitmap mode=12
254 | Brush gradient mode=64
255 | Brush gradient color=192 192 192
256 | Brush background image=
257 | Custom shape=
258 | Custom text mode=0
259 | Pen=1 0 255 128 128
260 | Shadow color=192 192 192
261 | Shadow=0
262 |
263 | [DisplayPreferences\Symbol\FRMELNK]
264 | CENTERFont=新宋体,8,N
265 | CENTERFont color=0, 0, 0
266 | Line style=1
267 | AutoAdjustToText=Yes
268 | Keep aspect=No
269 | Keep center=No
270 | Keep size=No
271 | Brush color=255 255 255
272 | Fill Color=Yes
273 | Brush style=1
274 | Brush bitmap mode=12
275 | Brush gradient mode=0
276 | Brush gradient color=118 118 118
277 | Brush background image=
278 | Custom shape=
279 | Custom text mode=0
280 | Pen=1 0 128 128 255
281 | Shadow color=192 192 192
282 | Shadow=0
283 |
284 | [DisplayPreferences\Symbol\FILO]
285 | OBJSTRNFont=新宋体,8,N
286 | OBJSTRNFont color=0, 0, 0
287 | DISPNAMEFont=新宋体,8,N
288 | DISPNAMEFont color=0, 0, 0
289 | LCNMFont=新宋体,8,N
290 | LCNMFont color=0, 0, 0
291 | AutoAdjustToText=Yes
292 | Keep aspect=No
293 | Keep center=No
294 | Keep size=No
295 | Width=4800
296 | Height=3600
297 | Brush color=255 255 255
298 | Fill Color=Yes
299 | Brush style=1
300 | Brush bitmap mode=12
301 | Brush gradient mode=0
302 | Brush gradient color=118 118 118
303 | Brush background image=
304 | Custom shape=
305 | Custom text mode=0
306 | Pen=1 0 0 0 255
307 | Shadow color=192 192 192
308 | Shadow=0
309 |
310 | [DisplayPreferences\Symbol\FRMPCKG]
311 | STRNFont=新宋体,8,N
312 | STRNFont color=0, 0, 0
313 | DISPNAMEFont=新宋体,8,N
314 | DISPNAMEFont color=0, 0, 0
315 | LABLFont=新宋体,8,N
316 | LABLFont color=0, 0, 0
317 | AutoAdjustToText=Yes
318 | Keep aspect=No
319 | Keep center=No
320 | Keep size=No
321 | Width=4800
322 | Height=3600
323 | Brush color=255 255 192
324 | Fill Color=Yes
325 | Brush style=6
326 | Brush bitmap mode=12
327 | Brush gradient mode=65
328 | Brush gradient color=255 255 255
329 | Brush background image=
330 | Custom shape=
331 | Custom text mode=0
332 | Pen=1 0 178 178 178
333 | Shadow color=192 192 192
334 | Shadow=0
335 |
336 | [DisplayPreferences\Symbol\USRDEPD]
337 | OBJXSTRFont=新宋体,8,N
338 | OBJXSTRFont color=0, 0, 0
339 | Line style=1
340 | AutoAdjustToText=Yes
341 | Keep aspect=No
342 | Keep center=No
343 | Keep size=No
344 | Brush color=255 255 255
345 | Fill Color=Yes
346 | Brush style=1
347 | Brush bitmap mode=12
348 | Brush gradient mode=0
349 | Brush gradient color=118 118 118
350 | Brush background image=
351 | Custom shape=
352 | Custom text mode=0
353 | Pen=2 0 128 128 255
354 | Shadow color=192 192 192
355 | Shadow=0
356 |
357 | [DisplayPreferences\Symbol\Free Symbol]
358 | Free TextFont=新宋体,8,N
359 | Free TextFont color=0, 0, 0
360 | Line style=0
361 | AutoAdjustToText=Yes
362 | Keep aspect=No
363 | Keep center=No
364 | Keep size=No
365 | Brush color=255 255 255
366 | Fill Color=Yes
367 | Brush style=1
368 | Brush bitmap mode=12
369 | Brush gradient mode=0
370 | Brush gradient color=118 118 118
371 | Brush background image=
372 | Custom shape=
373 | Custom text mode=0
374 | Pen=1 0 0 0 255
375 | Shadow color=192 192 192
376 | Shadow=0
377 | (8268, 11693)
378 | ((315,354), (433,354))
379 | 1
380 | 15
381 |
382 |
383 | 1464181811
384 | 1464181870
385 | ((-12337,18621), (9562,-3727))
386 | 4130
387 | 0
388 | 0
389 | 3
390 | 16777215
391 | 12632256
392 | 新宋体,8,N
393 |
394 |
395 | 1464181602
396 | 1464181680
397 | ((-3575,-6469), (-3103,-475))
398 | ((-3273,-6469),(-3406,-475))
399 | 0
400 | 1
401 | 0
402 | 12632256
403 | 新宋体,8,N
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 | 1464181608
413 | 1464181698
414 | ((-3753,-1230), (-3303,4191))
415 | ((-3530,-1230),(-3526,1031),(-3526,4191))
416 | 0
417 | 1
418 | 0
419 | 12632256
420 | 新宋体,8,N
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 | 1464181612
430 | 1464181705
431 | ((-3999,2765), (-3549,8116))
432 | ((-3774,2765),(-3774,5617),(-3774,8116))
433 | 0
434 | 1
435 | 0
436 | 12632256
437 | 新宋体,8,N
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 | 1464181616
447 | 1464181777
448 | ((-5362,6504), (-4912,12255))
449 | ((-5138,6504),(-5137,12255))
450 | 0
451 | 1
452 | 0
453 | 12632256
454 | 新宋体,8,N
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 | 1464181621
464 | 1464181784
465 | ((-5548,11202), (-5098,16509))
466 | ((-5323,11202),(-5323,16509))
467 | 0
468 | 1
469 | 0
470 | 12632256
471 | 新宋体,8,N
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 | 1464181628
481 | 1464181785
482 | ((-2821,11264), (-2371,17066))
483 | ((-2596,17066),(-2596,11264))
484 | 0
485 | 1
486 | 0
487 | 12632256
488 | 新宋体,8,N
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 | 1464181632
498 | 1464181779
499 | ((-2511,6442), (-2061,12317))
500 | ((-2287,12317),(-2286,6442))
501 | 0
502 | 1
503 | 0
504 | 12632256
505 | 新宋体,8,N
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 | 1464181634
515 | 1464181780
516 | ((1208,6690), (1658,12825))
517 | ((1433,6690),(1433,12825))
518 | 0
519 | 1
520 | 0
521 | 12632256
522 | 新宋体,8,N
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 | 1464181638
532 | 1464181782
533 | ((3997,6690), (4447,12577))
534 | ((4221,12577),(4222,6690))
535 | 0
536 | 1
537 | 0
538 | 12632256
539 | 新宋体,8,N
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 | 1464181640
549 | 1464181703
550 | ((3195,-1230), (3648,8054))
551 | ((3416,8054),(3416,2828),(3426,-1230))
552 | 0
553 | 1
554 | 0
555 | 12632256
556 | 新宋体,8,N
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 | 1464181642
566 | 1464181701
567 | ((3306,-5788), (3775,-98))
568 | ((3488,-98),(3593,-5788))
569 | 0
570 | 1
571 | 0
572 | 12632256
573 | 新宋体,8,N
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
582 | 浏览器
583 | 1464181328
584 | 1464181660
585 | ((-7945,-5599), (6005,-9799))
586 | 4130
587 | 0
588 | 0
589 | 16777215
590 | 12632256
591 | 新宋体,8,N
592 | 1
593 |
594 |
595 | 路由(route)
596 | 1464181450
597 | 1464181720
598 | ((-8100,2172), (300,4722))
599 | 4130
600 | 0
601 | 0
602 | 16777215
603 | 12632256
604 | 新宋体,8,N
605 |
606 |
607 | 请求处理器(request handler)
608 | 1464181457
609 | 1464181758
610 | ((-8100,6149), (5700,8699))
611 | 4130
612 | 0
613 | 0
614 | 16777215
615 | 12632256
616 | 新宋体,8,N
617 | 1
618 |
619 |
620 | orm
621 | 1464181461
622 | 1464181764
623 | ((-8024,10724), (-1350,12974))
624 | 4130
625 | 0
626 | 0
627 | 16777215
628 | 12632256
629 | 新宋体,8,N
630 |
631 |
632 | 模板引擎
633 | 1464181463
634 | 1464181769
635 | ((-374,10725), (5700,13049))
636 | 4130
637 | 0
638 | 0
639 | 16777215
640 | 12632256
641 | 新宋体,8,N
642 | 1
643 |
644 |
645 | 数据库
646 | 1464181468
647 | 1464181775
648 | ((-8250,15299), (5550,17549))
649 | 4130
650 | 0
651 | 0
652 | 16777215
653 | 12632256
654 | 新宋体,8,N
655 |
656 |
657 | 服务器软件
658 | 1464181548
659 | 1464181749
660 | ((-8064,-1784), (6034,540))
661 | 4130
662 | 0
663 | 0
664 | 16777215
665 | 12632256
666 | 新宋体,8,N
667 |
668 |
669 | 服务器
670 | 1464181878
671 | 1464181906
672 | ((-12019,16559), (-9400,18358))
673 | 4130
674 | 0
675 | 16777215
676 | 16777215
677 | 12632256
678 | 新宋体,8,N
679 | 1
680 |
681 |
682 |
683 |
684 |
685 |
686 |
687 |
688 |
689 |
690 |
691 |
--------------------------------------------------------------------------------