├── README.md ├── static ├── favicon.ico ├── img │ ├── down.png │ ├── more.png │ ├── Thumbs.db │ └── search.fdbb782e.svg ├── fonts │ ├── icomoon.eot │ ├── icomoon.ttf │ ├── icomoon.woff │ └── icomoon.svg ├── css │ ├── reset.css │ ├── index.css │ ├── advanced.css │ ├── style.css │ ├── normalize.css │ ├── default.css │ └── result.css └── js │ ├── global.js │ ├── common.js │ ├── stopExecutionOnTimeout.js │ ├── sketch.min.js │ ├── pagination.js │ ├── prefixfree.min.js │ └── dat.gui.min.js ├── config.py ├── .gitattributes ├── __pycache__ ├── common.cpython-35.pyc ├── config.cpython-35.pyc └── moudels.cpython-35.pyc ├── .idea ├── misc.xml ├── modules.xml ├── Article_Search.iml └── workspace.xml ├── moudels.py ├── Article_Search.py ├── templates ├── result.html └── index.html └── common.py /README.md: -------------------------------------------------------------------------------- 1 | # Article_Search 2 | -------------------------------------------------------------------------------- /static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/static/favicon.ico -------------------------------------------------------------------------------- /static/img/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/static/img/down.png -------------------------------------------------------------------------------- /static/img/more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/static/img/more.png -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | from elasticsearch import Elasticsearch 2 | 3 | client = Elasticsearch(hosts=['127.0.0.1']) -------------------------------------------------------------------------------- /static/img/Thumbs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/static/img/Thumbs.db -------------------------------------------------------------------------------- /static/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/static/fonts/icomoon.eot -------------------------------------------------------------------------------- /static/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/static/fonts/icomoon.ttf -------------------------------------------------------------------------------- /static/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/static/fonts/icomoon.woff -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=python 2 | *.css linguist-language=python 3 | *.html linguist-language=python 4 | -------------------------------------------------------------------------------- /__pycache__/common.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/__pycache__/common.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/config.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/__pycache__/config.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/moudels.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smile0304/Article_Search/HEAD/__pycache__/moudels.cpython-35.pyc -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /static/css/reset.css: -------------------------------------------------------------------------------- 1 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font-size:100%;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}table{border-collapse:collapse;border-spacing:0} -------------------------------------------------------------------------------- /.idea/Article_Search.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | 17 | 20 | -------------------------------------------------------------------------------- /static/js/global.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function(){ 3 | 4 | // 去除虚线框(会影响效率) 5 | $("a,input:checkbox,input:radio,button,input:button").on('focus',function(){$(this).blur();}); 6 | 7 | }); 8 | 9 | 10 | function hideElement(currentElement, targetElement) { 11 | if (!$.isArray(targetElement)) { 12 | targetElement = [ targetElement ]; 13 | } 14 | $(document).on("click.hideElement", function(e) { 15 | var len = 0, $target = $(e.target); 16 | for (var i = 0, length = targetElement.length; i < length; i++) { 17 | $.each(targetElement[i], function(j, n) { 18 | if ($target.is($(n)) || $.contains($(n)[0], $target[0])) { 19 | len++; 20 | } 21 | }); 22 | } 23 | if ($.contains(currentElement[0], $target[0])) { 24 | len = 1; 25 | } 26 | if (len == 0) { 27 | currentElement.hide(); 28 | } 29 | }); 30 | }; -------------------------------------------------------------------------------- /static/img/search.fdbb782e.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /static/js/common.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by yli on 2017/4/21. 3 | */ 4 | 5 | var searchArr; 6 | //定义一个search的,判断浏览器有无数据存储(搜索历史) 7 | if(localStorage.search){ 8 | //如果有,转换成 数组的形式存放到searchArr的数组里(localStorage以字符串的形式存储,所以要把它转换成数组的形式) 9 | searchArr= localStorage.search.split(",") 10 | }else{ 11 | //如果没有,则定义searchArr为一个空的数组 12 | searchArr = []; 13 | } 14 | //把存储的数据显示出来作为搜索历史 15 | MapSearchArr(); 16 | 17 | 18 | $("#btn").on("click", function(){ 19 | var val = $("#inp").val(); 20 | //点击搜索按钮时,去重 21 | KillRepeat(val); 22 | //去重后把数组存储到浏览器localStorage 23 | localStorage.search = searchArr; 24 | //然后再把搜索内容显示出来 25 | MapSearchArr(); 26 | }); 27 | 28 | 29 | function MapSearchArr(){ 30 | var tmpHtml = ""; 31 | for (var i=0;i " 33 | } 34 | $("#keyname").html(tmpHtml); 35 | } 36 | //去重 37 | function KillRepeat(val){ 38 | var kill = 0; 39 | for (var i=0;ithis.STOP_ALL_MONITORING_TIMEOUT)return this.programNoLongerBeingMonitored=!0,!1;try{this._checkOnInfiniteLoop(o,t)}catch(n){return this._sendErrorMessageToEditor(),this.programKilledSoStopMonitoring=!0,!0}return!1},_sendErrorMessageToEditor:function(){try{if(this._shouldPostMessage()){var o={action:"infinite-loop",line:this._findAroundLineNumber()};parent.postMessage(JSON.stringify(o),"*")}else this._throwAnErrorToStopPen()}catch(t){this._throwAnErrorToStopPen()}},_shouldPostMessage:function(){return document.location.href.match(/boomerang/)},_throwAnErrorToStopPen:function(){throw"We found an infinite loop in your Pen. We've stopped the Pen from running. Please correct it or contact support@codepen.io."},_findAroundLineNumber:function(){var o=new Error,t=0;if(o.stack){var i=o.stack.match(/boomerang\S+:(\d+):\d+/);i&&(t=i[1])}return t},_checkOnInfiniteLoop:function(o,t){if(!this._loopTimers[o])return this._loopTimers[o]=t,!1;var i=t-this._loopTimers[o];if(i>this.MAX_TIME_IN_LOOP_WO_EXIT)throw"Infinite Loop found on loop: "+o},_getTime:function(){return+new Date}},window.CP.shouldStopExecution=function(o){return window.CP.PenTimer.shouldStopLoop(o)},window.CP.exitedLoop=function(o){window.CP.PenTimer.exitedLoop(o)}; -------------------------------------------------------------------------------- /static/fonts/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /moudels.py: -------------------------------------------------------------------------------- 1 | from elasticsearch_dsl import DocType, Date, Nested, Boolean, analyzer, InnerObjectWrapper, Completion, Keyword, Text, Integer 2 | from elasticsearch_dsl.connections import connections 3 | connections.create_connection(hosts=["localhost"]) 4 | 5 | from elasticsearch_dsl.analysis import CustomAnalyzer as _CustomAnalyzer 6 | 7 | class CustomAnalyzer(_CustomAnalyzer): 8 | def get_analysis_definition(self): 9 | return {} 10 | 11 | ik_analyzer = CustomAnalyzer("ik_max_word", filter=["lowercase"]) 12 | 13 | 14 | class Article_4houType(DocType): 15 | suggest = Completion(analyzer=ik_analyzer) #搜索建议 16 | image_local = Keyword() 17 | title = Text(analyzer="ik_max_word") 18 | url_id = Keyword() 19 | create_time = Date() 20 | url = Keyword() 21 | author = Keyword() 22 | tags = Text(analyzer="ik_max_word") 23 | watch_nums = Integer() 24 | comment_nums = Integer() 25 | praise_nums = Integer() 26 | content = Text(analyzer="ik_max_word") 27 | 28 | class Meta: 29 | index = "teachnical_4hou" 30 | doc_type = "A_4hou" 31 | 32 | class Article_anquankeType(DocType): 33 | suggest = Completion(analyzer=ik_analyzer) #搜索建议 34 | id = Integer() 35 | url = Keyword() 36 | title = Text(analyzer="ik_max_word") 37 | create_time = Date() 38 | cover_local = Keyword() 39 | watch_num = Integer() 40 | comment_num = Integer() 41 | tags = Text(analyzer="ik_max_word") 42 | author = Keyword() 43 | content = Text(analyzer="ik_max_word") 44 | 45 | class Meta: 46 | index = "article_anquanke" 47 | doc_type = "anquanke" 48 | 49 | 50 | class Article_freebuf(DocType): 51 | suggest = Completion(analyzer=ik_analyzer) #搜索建议 52 | image_local = Keyword() 53 | title = Text(analyzer="ik_max_word") 54 | url_id = Keyword() 55 | create_time = Date() 56 | url = Keyword() 57 | author = Keyword() 58 | tags = Text(analyzer="ik_max_word") 59 | watch_nums = Integer() 60 | comment_nums = Integer() 61 | content = Text(analyzer="ik_max_word") 62 | 63 | class Meta: 64 | index = "teachnical_freebuf" 65 | doc_type = "freebuf" 66 | 67 | 68 | if __name__ == "__main__": 69 | Article_freebuf.init() 70 | -------------------------------------------------------------------------------- /static/css/index.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | html{*overflow:auto;} 3 | #main{width:730px;margin:75px auto 0;} 4 | #main h1.title{width:600px;padding-top: 80px;position: relative;z-index: 99;} 5 | #bd{margin-bottom:20px;} 6 | .logo.large{margin:0px auto 10px auto;width:350px;height:144px;font-size: 3.5rem;text-align:center;text-transform: uppercase;color: #ffffff;} 7 | 8 | /*nav样式*/ 9 | .nav{margin-bottom:10px;margin-left: 2%;position: relative;z-index: 20;} 10 | .searchList{float:left;padding-left:5px;} 11 | .searchList .searchItem{float:left;margin-right:15px;font-size:14px;padding:0 0 2px 2px;cursor:pointer;height:18px;} 12 | .searchList .searchItem.current{color:#0080cc;border-bottom:2px solid #9cc813;font-weight:bold;} 13 | 14 | /*input搜索区域*/ 15 | .inputArea{position:relative;margin-bottom:65px;position: relative;z-index: 20;} 16 | .inputArea .searchInput{border:1px solid #bfbfbf;padding:0 15px;outline:none;height:40px;*height:39px;*line-height:40px;width:520px; background:url(../img/inputbg.png);font-size:14px;} 17 | .inputArea .searchButton{position:absolute;left:550px;*left:552px;*top:1px;width:106px;height:42px;*height:41px;background:url(../img/seachbtn.png) no-repeat;border:none;cursor:pointer;} 18 | /*高级搜索*/ 19 | .inputArea .advanced{position:absolute;font-size:14px;left:674px;top:12px;text-decoration:underline;} 20 | /*联想下拉区域*/ 21 | .inputArea .dataList{display:none;position:absolute;left:0;top:42px;*top:43px;width:100%;padding:10px 0;background:transparent;border-top:none;} 22 | .inputArea .dataList li{padding:2px 15px;font-size:16px; 23 | color: white;line-height: 16px} 24 | .inputArea .dataList li a{ 25 | color: #405869 !important; 26 | } 27 | .inputArea .dataList li:hover{background:hsla(0, 0%, 100%, .25);color:#0080cc;font-weight:bold;} 28 | .inputArea .dataList li:hover a{color: white !important;text-decoration: none} 29 | /*搜索历史区域*/ 30 | .historyArea{margin:0 auto;width:485px;padding-top: 310px;} 31 | .historyArea .history {margin-bottom:15px;} 32 | .historyArea .history label{font-weight:bold;} 33 | .historyArea .history a{margin-right:12px;} 34 | 35 | /*版权信息*/ 36 | .foot{position:absolute;bottom:0px;width:100%;} 37 | .foot .wrap{margin:0 auto;} 38 | .foot .copyright{position:relative;top:-35px;color:#ababab;text-align:center;} 39 | 40 | .home-search-input { 41 | padding: 0; 42 | width: 100%; 43 | height: 52px; 44 | border: 1px solid hsla(0, 0%, 100%, .12); 45 | border-radius: 32px; 46 | background: hsla(0, 0%, 100%, .25); 47 | outline: none; 48 | color: #fff; 49 | text-align: center; 50 | font-size: 25px 51 | } 52 | .home-search-icon{ 53 | position: absolute; 54 | top: 14px; 55 | right: 20px; 56 | width: 24px; 57 | height: 24px; 58 | } 59 | -------------------------------------------------------------------------------- /static/css/advanced.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | html{*overflow:auto;} 3 | #hd{padding:20px 10px;} 4 | .logo{float:left;margin-right:30px; height:33px;} 5 | /*input搜索区域*/ 6 | .inputArea{float:left;position:relative;} 7 | .inputArea .searchInput{border:1px solid #bfbfbf;padding:0 15px;outline:none;height:35px;*line-height:38px;width:350px; background:url(../img/inputbg.png);font-size:14px;} 8 | .inputArea .searchButton{position:absolute;left:382px;top:0;*top:1px;*left:381px;width:106px;height:38px;background:url(../img/btn_min.png) no-repeat;border:none; cursor:pointer;} 9 | 10 | /*返回搜索*/ 11 | .inputArea .back{position:absolute;font-size:14px;left:500px;top:12px;width:60px;text-decoration:underline;} 12 | 13 | /*分界区域*/ 14 | .divsion{margin-bottom:24px;height:36px;background:#f9f9f9;border-bottom:1px solid #e0e0e0;} 15 | 16 | /*高级搜索区域*/ 17 | .subfield{border-left:4px solid #9cc813;font-size:14px;font-weight:bold;padding:2px 0 2px 20px;} 18 | .subfieldContent{padding-left:140px;padding-bottom:40px;} 19 | .subfieldContent .advanceItem{padding-left:350px;margin-bottom:15px;padding-top:8px;padding-bottom:3px;} 20 | .subfieldContent .advanceItem.keyWords{background:#f4f4f4;padding-top:18px;padding-bottom:3px;} 21 | .subfieldContent .advanceItem dd{float:left;margin-left:-320px;} 22 | .subfieldContent .advanceItem dd label{float:left;margin-right:40px;width:75px;font-weight:bold;} 23 | .subfieldContent .advanceItem dd .impInfo{ font-weight:bold;} 24 | .subfieldContent .advanceItem dd .tips{float:left;} 25 | .subfieldContent .advanceItem dd p, .subfieldContent .advanceItem dt p{margin-bottom:10px;height:26px;} 26 | .subfieldContent .advanceItem dt p input[type=text]{position:relative;top:-5px;line-height:26px;} 27 | 28 | .subfieldContent .advanceItem dt{float:left;width:100%;} 29 | .subfieldContent .advanceItem.keyWords dt input[type=text]{width:290px;height:26px;border:1px solid #bfbfbf;outline:none;} 30 | /*自定义*/ 31 | .subfieldContent .advanceItem.time{height:30px;} 32 | .subfieldContent .advanceItem .define{display:none;position:relative;*top:-3px;} 33 | .subfieldContent .advanceItem.time input[type=text]{width:80px;height:18px;line-height:18px;border:1px solid #bfbfbf;outline:none;} 34 | 35 | 36 | 37 | 38 | 39 | /*更多按钮*/ 40 | .more {float:left;} 41 | .more:hover{text-decoration:none;} 42 | .more .moreIcon{display:inline-block;position:relative;top:-1px;*top:-3px;left:2px;*left:-1px;width:9px;height:5px;background:url(../img/more.png);} 43 | .more.show .moreIcon{background:url(../img/down.png);top:-2px;} 44 | 45 | /*立即搜索样式*/ 46 | .subfieldContent .search{margin:45px 0 0 145px;width:130px;height:36px;background:url(../img/btnbg.png); font-weight:bold;border:none;border:1px solid #bfbfbf;line-height:36px;cursor:pointer;font-size:14px;} 47 | /*联想下拉区域*/ 48 | .inputArea .dataList{display:none;position:absolute;left:0;top:42px;*top:43px;width:550px;padding:5px 0;background:#fff;border:1px solid #bfbfbf;border-top:none;} 49 | .inputArea .dataList li{padding:2px 15px;font-size:14px;} 50 | .inputArea .dataList li:hover{background:#f0f0f0;color:#0080cc;font-weight:bold;} 51 | -------------------------------------------------------------------------------- /static/css/style.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | /*css reset*/ 3 | html, body, div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, code, del, dfn, em, img, q, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td , i{ 4 | margin:0; 5 | padding:0; 6 | border:0; 7 | font-weight:inherit; 8 | font-style:inherit; 9 | font-size:100%; 10 | font-family:inherit; 11 | vertical-align:baseline; 12 | } 13 | body {line-height:1.5;} 14 | table {border-collapse: collapse;border-spacing:0;} 15 | caption, th, td ,b,strong{text-align:left;font-weight:normal;} 16 | table, td, th {vertical-align:middle;} 17 | blockquote:before, blockquote:after, q:before, q:after {content:"";} 18 | blockquote, q {quotes:"" "";} 19 | a img {border:none;} 20 | em,cite{font-style:normal;} 21 | 22 | 23 | body { background:#fff; font: 12px/1.5 Tahoma,'宋体';color:#000;} 24 | h1, h2, h3, h4, h5, h6 {font-weight:normal;color:#111;} 25 | a {text-decoration:none;cursor:pointer;} 26 | dl, dt, dd, ol, ul, li{ list-style:none;} 27 | 28 | /*some common class*/ 29 | .left{float:left;} 30 | .right{float:right;} 31 | 32 | /*clear*/ 33 | .ue-clear:after{content: ".";display:block;height:0;clear:both;visibility:hidden;} 34 | .ue-clear{display:inline-block;} 35 | *html .ue-clear{height:1%;} 36 | .ue-clear{display:block;} 37 | 38 | a{color:#0080cc;} 39 | a:hover{color:#267A01;text-decoration:underline;} 40 | /*logo样式*/ 41 | .logo{width:160px;height:47px;padding:0 5px;} 42 | 43 | /*choose样式*/ 44 | .choose{float:left;margin-right:15px;white-space:nowrap;} 45 | .choose .text{float:left;padding-left:20px;*padding-left:16px;white-space:nowrap; vertical-align:text-bottom;} 46 | .choose input[type=radio],.choose input[type=checkbox]{position:relative;*top:-3px;float:left;margin-right:-16px;} 47 | 48 | /*==================================== 49 | 分页信息(表格依赖样式) 50 | ===================================*/ 51 | .pagination{font-size:14px;} 52 | .pagination a {text-decoration: none;border: solid 1px; } 53 | .pagination .pxofy{float:left;margin-left: 5px;height:25px;*padding-top:1px;} 54 | .pagination a, .pagination span {display: block;float: left;height:18px;line-height:18px;padding:0 6px;margin-right: 5px;font-family:Arial, Helvetica, sans-serif !important;} 55 | .pagination .current {cursor:default;border: solid 1px ;} 56 | .pagination .prev, .pagination .next{*line-height:22px;} 57 | 58 | /*分页样式*/ 59 | .pagination a{color:#ffffff;border-radius: 5px;padding: 4px 7px; font-weight: 700;border-color:#eeeff4;background-color: #ccc;} 60 | .pagination a:hover{color:#ffffff;border-color:#8EB2D2;background:#000000;} 61 | .pagination .current{color:#ffffff;border-radius: 5px;padding: 4px 7px; font-weight: 700;border-color:#eeeff4;background:#29c06d;} 62 | .pagination .current.prev, .pagination .current.next{color:#ffffff;border-color:#eeeff4;background:#ccc;border-radius: 5px;padding: 4px 7px; font-weight: 700;} 63 | .pagination .pxofy{color: #023054;} 64 | 65 | #foot{height:32px;line-height:32px; text-align:center;background:#f9f9f9;border-top:1px solid #e0e0e0;color:#ababab;} 66 | 67 | .canvas{ 68 | position: absolute; 69 | left: 0; 70 | top:0; 71 | z-index: -1; 72 | } 73 | -------------------------------------------------------------------------------- /static/css/normalize.css: -------------------------------------------------------------------------------- 1 | article, 2 | aside, 3 | details, 4 | figcaption, 5 | figure, 6 | footer, 7 | header, 8 | hgroup, 9 | main, 10 | nav, 11 | section, 12 | summary { 13 | display: block; 14 | } 15 | 16 | audio, 17 | canvas, 18 | video { 19 | display: inline-block; 20 | } 21 | 22 | /*audio:not([controls]) { 23 | display: none; 24 | height: 0; 25 | }*/ 26 | 27 | [hidden] { 28 | display: none; 29 | } 30 | 31 | html { 32 | font-family: sans-serif; 33 | -ms-text-size-adjust: 100%; 34 | -webkit-text-size-adjust: 100%; 35 | } 36 | 37 | body { 38 | margin: 0; 39 | } 40 | 41 | a:focus { 42 | outline: thin dotted; 43 | } 44 | 45 | a:active, 46 | a:hover { 47 | outline: 0; 48 | } 49 | 50 | h1 { 51 | font-size: 2em; 52 | margin: 0.67em 0; 53 | } 54 | 55 | abbr[title] { 56 | border-bottom: 1px dotted; 57 | } 58 | 59 | b, 60 | strong { 61 | font-weight: bold; 62 | } 63 | 64 | dfn { 65 | font-style: italic; 66 | } 67 | 68 | hr { 69 | -moz-box-sizing: content-box; 70 | box-sizing: content-box; 71 | height: 0; 72 | } 73 | 74 | mark { 75 | background: #ff0; 76 | color: #000; 77 | } 78 | 79 | code, 80 | kbd, 81 | pre, 82 | samp { 83 | font-family: monospace, serif; 84 | font-size: 1em; 85 | } 86 | 87 | pre { 88 | white-space: pre-wrap; 89 | } 90 | 91 | q { 92 | quotes: "\201C" "\201D" "\2018" "\2019"; 93 | } 94 | 95 | small { 96 | font-size: 80%; 97 | } 98 | 99 | sub, 100 | sup { 101 | font-size: 75%; 102 | line-height: 0; 103 | position: relative; 104 | vertical-align: baseline; 105 | } 106 | 107 | sup { 108 | top: -0.5em; 109 | } 110 | 111 | sub { 112 | bottom: -0.25em; 113 | } 114 | 115 | img { 116 | border: 0; 117 | } 118 | 119 | svg:not(:root) { 120 | overflow: hidden; 121 | } 122 | 123 | figure { 124 | margin: 0; 125 | } 126 | 127 | fieldset { 128 | border: 1px solid #c0c0c0; 129 | margin: 0 2px; 130 | padding: 0.35em 0.625em 0.75em; 131 | } 132 | 133 | legend { 134 | border: 0; 135 | padding: 0; 136 | } 137 | 138 | button, 139 | input, 140 | select, 141 | textarea { 142 | font-family: inherit; 143 | font-size: 100%; 144 | margin: 0; 145 | } 146 | 147 | button, 148 | input { 149 | line-height: normal; 150 | } 151 | 152 | button, 153 | select { 154 | text-transform: none; 155 | } 156 | 157 | button, 158 | html input[type="button"], 159 | input[type="reset"], 160 | input[type="submit"] { 161 | -webkit-appearance: button; 162 | cursor: pointer; 163 | } 164 | 165 | button[disabled], 166 | html input[disabled] { 167 | cursor: default; 168 | } 169 | 170 | input[type="checkbox"], 171 | input[type="radio"] { 172 | box-sizing: border-box; 173 | padding: 0; 174 | } 175 | 176 | input[type="search"] { 177 | -webkit-appearance: textfield; 178 | -moz-box-sizing: content-box; 179 | -webkit-box-sizing: content-box; 180 | box-sizing: content-box; 181 | } 182 | 183 | input[type="search"]::-webkit-search-cancel-button, 184 | input[type="search"]::-webkit-search-decoration { 185 | -webkit-appearance: none; 186 | } 187 | 188 | button::-moz-focus-inner, 189 | input::-moz-focus-inner { 190 | border: 0; 191 | padding: 0; 192 | } 193 | 194 | textarea { 195 | overflow: auto; 196 | vertical-align: top; 197 | } 198 | 199 | table { 200 | border-collapse: collapse; 201 | border-spacing: 0; 202 | } -------------------------------------------------------------------------------- /Article_Search.py: -------------------------------------------------------------------------------- 1 | from flask import Flask,render_template,request 2 | from config import client 3 | from moudels import Article_4houType,Article_anquankeType,Article_freebuf 4 | from common import elasticsearch_search,elasticsearch_allsearch,get_elasticsearch_data_count 5 | import json 6 | from datetime import datetime 7 | app = Flask(__name__) 8 | 9 | 10 | @app.route('/') 11 | def search_index(): 12 | return render_template("index.html") 13 | 14 | @app.route('/suggest/') 15 | def suggest(): 16 | key_words = request.args.get('s','') 17 | type = request.args.get('s_type','') 18 | if "A4hou" == type: 19 | fuzzing = elasticsearch_search(type=Article_4houType) 20 | re_dates = fuzzing.return_fuzzing_search(key_words=key_words) 21 | elif "anquanke" == type: 22 | fuzzing = elasticsearch_search(type=Article_anquankeType) 23 | re_dates = fuzzing.return_fuzzing_search(key_words=key_words) 24 | elif "freebuf" == type: 25 | fuzzing = elasticsearch_search(type=Article_freebuf) 26 | re_dates = fuzzing.return_fuzzing_search(key_words=key_words) 27 | else: 28 | fuzzing = elasticsearch_allsearch() 29 | re_dates = fuzzing.return_fuzzing_search(key_words=key_words) 30 | return json.dumps(re_dates) 31 | 32 | @app.route('/search/') 33 | def search(): 34 | #文章来源 35 | all_options = [["all","全部"],["A4hou","嘶吼"],["anquanke","安全客"],["freebuf","freebuf"]] #不明白为什么用字典会乱序 36 | key_words = request.args.get('q','') 37 | types = request.args.get('s_type','') 38 | page = request.args.get('p','1') 39 | try: 40 | page = int(page) 41 | except: 42 | page = 1 43 | if "A4hou" == types: 44 | search_obj = elasticsearch_search(type=Article_4houType) 45 | response, last_seconds = search_obj.get_date(key_words=key_words, page=page) 46 | total_nums = response["hits"]["total"] 47 | all_hits = search_obj.analyze_date(key_words, response) 48 | elif "anquanke" == types: 49 | search_obj = elasticsearch_search(type=Article_anquankeType) 50 | response, last_seconds = search_obj.get_date(key_words=key_words, page=page) 51 | total_nums = response["hits"]["total"] 52 | all_hits = search_obj.analyze_date(key_words, response) 53 | elif "freebuf" == types: 54 | search_obj = elasticsearch_search(type=Article_freebuf) 55 | response, last_seconds = search_obj.get_date(key_words=key_words, page=page) 56 | total_nums = response["hits"]["total"] 57 | all_hits = search_obj.analyze_date(key_words, response) 58 | elif "all" == types: 59 | search_obj = elasticsearch_allsearch() 60 | all_hits,last_seconds,total_nums = search_obj.return_datenum(key_words,page) 61 | x = get_elasticsearch_data_count() 62 | alldate_nums = x.return_count() 63 | if (page%12) > 0: 64 | page_nums = int(total_nums/12)+1 65 | else: 66 | page_nums = int(total_nums/12) 67 | 68 | 69 | 70 | return render_template("result.html", 71 | alldate_nums = alldate_nums, 72 | page=page, 73 | all_hits=all_hits, 74 | key_words=key_words, 75 | total_nums=total_nums, 76 | page_nums=page_nums, 77 | last_seconds=last_seconds, 78 | type = types, 79 | all_options = all_options 80 | ) 81 | 82 | if __name__ == '__main__': 83 | app.run(host="127.0.0.1",debug=True,port=8080) 84 | -------------------------------------------------------------------------------- /static/js/sketch.min.js: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2013 Justin Windle, http://soulwire.co.uk */ 2 | !function(e,t){"object"==typeof exports?module.exports=t(e,e.document):"function"==typeof define&&define.amd?define(function(){return t(e,e.document)}):e.Sketch=t(e,e.document)}(typeof window!=="undefined"?window:this,function(e,t){"use strict";function n(e){return"[object Array]"==Object.prototype.toString.call(e)}function o(e){return"function"==typeof e}function r(e){return"number"==typeof e}function i(e){return"string"==typeof e}function u(e){return C[e]||String.fromCharCode(e)}function a(e,t,n){for(var o in t)!n&&o in e||(e[o]=t[o]);return e}function c(e,t){return function(){e.apply(t,arguments)}}function s(e){var t={};for(var n in e)t[n]=o(e[n])?c(e[n],e):e[n];return t}function l(e){function t(t){o(t)&&t.apply(e,[].splice.call(arguments,1))}function n(e){for(_=0;_ ne_half ? Math.max(Math.min(current_page 33 | - ne_half, upper_limit), 0) : 0; 34 | var end = current_page > ne_half ? Math.min(current_page + ne_half, 35 | np) : Math.min(opts.num_display_entries, np); 36 | return [start, end]; 37 | } 38 | 39 | /** 40 | * 点击事件 41 | */ 42 | function pageSelected(page_id, evt) { 43 | var page_id = parseInt(page_id); 44 | current_page = page_id; 45 | 46 | drawLinks(); 47 | var continuePropagation = opts.callback(page_id, panel); 48 | if (!continuePropagation) { 49 | if (evt.stopPropagation) { 50 | evt.stopPropagation(); 51 | } else { 52 | evt.cancelBubble = true; 53 | } 54 | } 55 | return continuePropagation; 56 | } 57 | 58 | /** 59 | * 链接 60 | */ 61 | function drawLinks() { 62 | panel.empty(); 63 | var interval = getInterval(); 64 | var np = numPages(); 65 | var getClickHandler = function(page_id) { 66 | return function(evt) { 67 | return pageSelected(page_id + 1, evt); 68 | } 69 | } 70 | 71 | var appendItem = function(page_id, appendopts) { 72 | 73 | page_id = page_id < 0 ? 0 : (page_id < np ? page_id : np-1); 74 | appendopts = jQuery.extend({ 75 | text : page_id+1, 76 | classes : "" 77 | }, appendopts || {}); 78 | 79 | if (page_id == current_page) { 80 | var lnk = $("" + (appendopts.text) 81 | + ""); 82 | } else { 83 | var lnk = $("" + (appendopts.text) + "").bind( 84 | "click", getClickHandler(page_id)).attr('href', 85 | opts.link_to.replace(/__id__/, page_id)); 86 | 87 | } 88 | if (appendopts.classes) { 89 | lnk.addClass(appendopts.classes); 90 | } 91 | panel.append(lnk); 92 | } 93 | // 上一页 94 | if (opts.prev_text && (current_page > 0 || opts.prev_show_always)) { 95 | appendItem(current_page - 1, { 96 | text : opts.prev_text, 97 | classes : "prev" 98 | }); 99 | } 100 | // 点点点 101 | if (interval[0] > 0 && opts.num_edge_entries > 0) { 102 | var end = Math.min(opts.num_edge_entries, interval[0]); 103 | for (var i = 0; i < end; i++) { 104 | appendItem(i); 105 | } 106 | if (opts.num_edge_entries < interval[0] && opts.ellipse_text) { 107 | jQuery("" + opts.ellipse_text + "") 108 | .appendTo(panel); 109 | } 110 | } 111 | // 中间的页码 112 | for (var i = interval[0]; i < interval[1]; i++) { 113 | appendItem(i); 114 | } 115 | // 最后的页码 116 | if (interval[1] < np && opts.num_edge_entries > 0) { 117 | if (np - opts.num_edge_entries > interval[1] 118 | && opts.ellipse_text) { 119 | jQuery("" + opts.ellipse_text + "") 120 | .appendTo(panel); 121 | } 122 | var begin = Math.max(np - opts.num_edge_entries, interval[1]); 123 | for (var i = begin; i < np; i++) { 124 | appendItem(i); 125 | } 126 | 127 | } 128 | // 下一页 129 | if (opts.next_text 130 | && (current_page < np - 1 || opts.next_show_always)) { 131 | appendItem(current_page + 1, { 132 | text : opts.next_text, 133 | classes : "next" 134 | }); 135 | } 136 | // 记录显示 137 | if (opts.display_msg) { 138 | if(!maxentries){ 139 | panel 140 | .append('
暂时无数据可以显示
'); 141 | }else{ 142 | panel 143 | .append('
显示第 ' 144 | + ((current_page * opts.items_per_page) + 1) 145 | + ' 条到 ' 146 | + (((current_page + 1) * opts.items_per_page) > maxentries 147 | ? maxentries 148 | : ((current_page + 1) * opts.items_per_page)) 149 | + ' 条记录,总共 ' + maxentries + ' 条
'); 150 | } 151 | } 152 | //设置跳到第几页 153 | if(opts.setPageNo){ 154 | panel.append("
跳转到
"); 155 | } 156 | } 157 | 158 | // 当前页 159 | var current_page = opts.current_page; 160 | maxentries = ( maxentries < 0) ? 0 : maxentries; 161 | opts.items_per_page = (!opts.items_per_page || opts.items_per_page < 0) 162 | ? 1 163 | : opts.items_per_page; 164 | var panel = jQuery(this); 165 | this.selectPage = function(page_id) { 166 | pageSelected(page_id); 167 | } 168 | this.prevPage = function() { 169 | if (current_page > 0) { 170 | pageSelected(current_page - 1); 171 | return true; 172 | } else { 173 | return false; 174 | } 175 | } 176 | this.nextPage = function() { 177 | if (current_page < numPages() - 1) { 178 | pageSelected(current_page + 1); 179 | return true; 180 | } else { 181 | return false; 182 | } 183 | } 184 | 185 | if(maxentries==0){ 186 | panel.append(''+opts.prev_text+''+opts.next_text+'
暂时无数据可以显示
'); 187 | }else{ 188 | drawLinks(); 189 | } 190 | $(this).find(".goto button").live("click",function(evt){ 191 | var setPageNo = $(this).parent().find("input").val(); 192 | if(setPageNo!=null && setPageNo!=""&&setPageNo>0&&setPageNo<=numPages()){ 193 | pageSelected(setPageNo-1, evt); 194 | } 195 | }); 196 | }); 197 | } 198 | -------------------------------------------------------------------------------- /static/css/default.css: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Raleway:200,500,700,800); 2 | @font-face { 3 | font-family: 'icomoon'; 4 | src:url('../fonts/icomoon.eot?rretjt'); 5 | /*src:url('../fonts/icomoon.eot?#iefixrretjt') format('embedded-opentype'),*/ 6 | url('../fonts/icomoon.woff?rretjt') format('woff'), 7 | url('../fonts/icomoon.ttf?rretjt') format('truetype'), 8 | url('../fonts/icomoon.svg?rretjt#icomoon') format('svg'); 9 | font-weight: normal; 10 | font-style: normal; 11 | } 12 | 13 | [class^="icon-"], [class*=" icon-"] { 14 | font-family: 'icomoon'; 15 | speak: none; 16 | font-style: normal; 17 | font-weight: normal; 18 | font-variant: normal; 19 | text-transform: none; 20 | line-height: 1; 21 | 22 | /* Better Font Rendering =========== */ 23 | -webkit-font-smoothing: antialiased; 24 | -moz-osx-font-smoothing: grayscale; 25 | } 26 | 27 | body, html { font-size: 100%; padding: 0; margin: 0;} 28 | 29 | /* Reset */ 30 | *, 31 | *:after, 32 | *:before { 33 | -webkit-box-sizing: border-box; 34 | -moz-box-sizing: border-box; 35 | box-sizing: border-box; 36 | } 37 | 38 | /* Clearfix hack by Nicolas Gallagher: http://nicolasgallagher.com/micro-clearfix-hack/ */ 39 | .clearfix:before, 40 | .clearfix:after { 41 | content: " "; 42 | display: table; 43 | } 44 | 45 | .clearfix:after { 46 | clear: both; 47 | } 48 | 49 | body{ 50 | background: #f9f7f6; 51 | color: #404d5b; 52 | font-weight: 500; 53 | font-size: 1.05em; 54 | font-family: "Segoe UI", "Lucida Grande", Helvetica, Arial, "Microsoft YaHei", FreeSans, Arimo, "Droid Sans", "wenquanyi micro hei", "Hiragino Sans GB", "Hiragino Sans GB W3", "FontAwesome", sans-serif; 55 | } 56 | a{color: #2fa0ec;text-decoration: none;outline: none;} 57 | a:hover,a:focus{color:#74777b;} 58 | 59 | .htmleaf-container{ 60 | margin: 0 auto; 61 | text-align: center; 62 | overflow: hidden; 63 | } 64 | .htmleaf-content { 65 | font-size: 150%; 66 | padding: 1em 0; 67 | } 68 | 69 | .htmleaf-content h2 { 70 | margin: 0 0 2em; 71 | opacity: 0.1; 72 | } 73 | 74 | .htmleaf-content p { 75 | margin: 1em 0; 76 | padding: 5em 0 0 0; 77 | font-size: 0.65em; 78 | } 79 | .bgcolor-1 { background: #f0efee; } 80 | .bgcolor-2 { background: #f9f9f9; } 81 | .bgcolor-3 { background: #e8e8e8; }/*light grey*/ 82 | .bgcolor-4 { background: #2f3238; color: #fff; }/*Dark grey*/ 83 | .bgcolor-5 { background: #df6659; color: #521e18; }/*pink1*/ 84 | .bgcolor-6 { background: #2fa8ec; }/*sky blue*/ 85 | .bgcolor-7 { background: #d0d6d6; }/*White tea*/ 86 | .bgcolor-8 { background: #3d4444; color: #fff; }/*Dark grey2*/ 87 | .bgcolor-9 { background: #ef3f52; color: #fff;}/*pink2*/ 88 | .bgcolor-10{ background: #64448f; color: #fff;}/*Violet*/ 89 | .bgcolor-11{ background: #3755ad; color: #fff;}/*dark blue*/ 90 | .bgcolor-12{ background: #3498DB; color: #fff;}/*light blue*/ 91 | /* Header */ 92 | .htmleaf-header{ 93 | padding: 1em 190px 1em; 94 | letter-spacing: -1px; 95 | text-align: center; 96 | } 97 | .htmleaf-header h1 { 98 | font-weight: 600; 99 | font-size: 2em; 100 | line-height: 1; 101 | margin-bottom: 0; 102 | font-family: "Segoe UI", "Lucida Grande", Helvetica, Arial, "Microsoft YaHei", FreeSans, Arimo, "Droid Sans", "wenquanyi micro hei", "Hiragino Sans GB", "Hiragino Sans GB W3", "FontAwesome", sans-serif; 103 | } 104 | .htmleaf-header h1 span { 105 | font-family: "Segoe UI", "Lucida Grande", Helvetica, Arial, "Microsoft YaHei", FreeSans, Arimo, "Droid Sans", "wenquanyi micro hei", "Hiragino Sans GB", "Hiragino Sans GB W3", "FontAwesome", sans-serif; 106 | display: block; 107 | font-size: 60%; 108 | font-weight: 400; 109 | padding: 0.8em 0 0.5em 0; 110 | color: #c3c8cd; 111 | } 112 | /*nav*/ 113 | .htmleaf-demo a{color: #1d7db1;text-decoration: none;} 114 | .htmleaf-demo{width: 100%;padding-bottom: 1.2em;} 115 | .htmleaf-demo a{display: inline-block;margin: 0.5em;padding: 0.6em 1em;border: 3px solid #1d7db1;font-weight: 700;} 116 | .htmleaf-demo a:hover{opacity: 0.6;} 117 | .htmleaf-demo a.current{background:#1d7db1;color: #fff; } 118 | /* Top Navigation Style */ 119 | .htmleaf-links { 120 | position: relative; 121 | display: inline-block; 122 | white-space: nowrap; 123 | font-size: 1.5em; 124 | text-align: center; 125 | } 126 | 127 | .htmleaf-links::after { 128 | position: absolute; 129 | top: 0; 130 | left: 50%; 131 | margin-left: -1px; 132 | width: 2px; 133 | height: 100%; 134 | background: #dbdbdb; 135 | content: ''; 136 | -webkit-transform: rotate3d(0,0,1,22.5deg); 137 | transform: rotate3d(0,0,1,22.5deg); 138 | } 139 | 140 | .htmleaf-icon { 141 | display: inline-block; 142 | margin: 0.5em; 143 | padding: 0em 0; 144 | width: 1.5em; 145 | text-decoration: none; 146 | } 147 | 148 | .htmleaf-icon span { 149 | display: none; 150 | } 151 | 152 | .htmleaf-icon:before { 153 | margin: 0 5px; 154 | text-transform: none; 155 | font-weight: normal; 156 | font-style: normal; 157 | font-variant: normal; 158 | font-family: 'icomoon'; 159 | line-height: 1; 160 | speak: none; 161 | -webkit-font-smoothing: antialiased; 162 | } 163 | /* footer */ 164 | .htmleaf-footer{width: 100%;padding-top: 10px;} 165 | .htmleaf-small{font-size: 0.8em;} 166 | .center{text-align: center;} 167 | /****/ 168 | .related { 169 | color: #fff; 170 | background: #333; 171 | text-align: center; 172 | font-size: 1.25em; 173 | padding: 0.5em 0; 174 | overflow: hidden; 175 | } 176 | 177 | .related > a { 178 | vertical-align: top; 179 | width: calc(100% - 20px); 180 | max-width: 340px; 181 | display: inline-block; 182 | text-align: center; 183 | margin: 20px 10px; 184 | padding: 25px; 185 | font-family: "Segoe UI", "Lucida Grande", Helvetica, Arial, "Microsoft YaHei", FreeSans, Arimo, "Droid Sans", "wenquanyi micro hei", "Hiragino Sans GB", "Hiragino Sans GB W3", "FontAwesome", sans-serif; 186 | } 187 | .related a { 188 | display: inline-block; 189 | text-align: left; 190 | margin: 20px auto; 191 | padding: 10px 20px; 192 | opacity: 0.8; 193 | -webkit-transition: opacity 0.3s; 194 | transition: opacity 0.3s; 195 | -webkit-backface-visibility: hidden; 196 | } 197 | 198 | .related a:hover, 199 | .related a:active { 200 | opacity: 1; 201 | } 202 | 203 | .related a img { 204 | max-width: 100%; 205 | opacity: 0.8; 206 | border-radius: 4px; 207 | } 208 | .related a:hover img, 209 | .related a:active img { 210 | opacity: 1; 211 | } 212 | .related h3{font-family: "Microsoft YaHei", sans-serif;} 213 | .related a h3 { 214 | font-weight: 300; 215 | margin-top: 0.15em; 216 | color: #fff; 217 | } 218 | /* icomoon */ 219 | .icon-htmleaf-home-outline:before { 220 | content: "\e5000"; 221 | } 222 | 223 | .icon-htmleaf-arrow-forward-outline:before { 224 | content: "\e5001"; 225 | } 226 | 227 | @media screen and (max-width: 50em) { 228 | .htmleaf-header { 229 | padding: 3em 10% 4em; 230 | } 231 | .htmleaf-header h1 { 232 | font-size:2em; 233 | } 234 | } 235 | 236 | 237 | @media screen and (max-width: 40em) { 238 | .htmleaf-header h1 { 239 | font-size: 1.5em; 240 | } 241 | } 242 | 243 | @media screen and (max-width: 30em) { 244 | .htmleaf-header h1 { 245 | font-size:1.2em; 246 | } 247 | } -------------------------------------------------------------------------------- /static/js/prefixfree.min.js: -------------------------------------------------------------------------------- 1 | ! function() { 2 | function e(e, r) { 3 | return [].slice.call((r || document).querySelectorAll(e)) 4 | } 5 | if(window.addEventListener) { 6 | var r = window.StyleFix = { 7 | link: function(e) { 8 | try { 9 | if("stylesheet" !== e.rel || e.hasAttribute("data-noprefix")) return 10 | } catch(t) { 11 | return 12 | } 13 | var n, i = e.href || e.getAttribute("data-href"), 14 | a = i.replace(/[^\/]+$/, ""), 15 | o = (/^[a-z]{3,10}:/.exec(a) || [""])[0], 16 | s = (/^[a-z]{3,10}:\/\/[^\/]+/.exec(a) || [""])[0], 17 | l = /^([^?]*)\??/.exec(i)[1], 18 | u = e.parentNode, 19 | p = new XMLHttpRequest; 20 | p.onreadystatechange = function() { 21 | 4 === p.readyState && n() 22 | }, n = function() { 23 | var t = p.responseText; 24 | if(t && e.parentNode && (!p.status || p.status < 400 || p.status > 600)) { 25 | if(t = r.fix(t, !0, e), a) { 26 | t = t.replace(/url\(\s*?((?:"|')?)(.+?)\1\s*?\)/gi, function(e, r, t) { 27 | return /^([a-z]{3,10}:|#)/i.test(t) ? e : /^\/\//.test(t) ? 'url("' + o + t + '")' : /^\//.test(t) ? 'url("' + s + t + '")' : /^\?/.test(t) ? 'url("' + l + t + '")' : 'url("' + a + t + '")' 28 | }); 29 | var n = a.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g, "\\$1"); 30 | t = t.replace(RegExp("\\b(behavior:\\s*?url\\('?\"?)" + n, "gi"), "$1") 31 | } 32 | var i = document.createElement("style"); 33 | i.textContent = t, i.media = e.media, i.disabled = e.disabled, i.setAttribute("data-href", e.getAttribute("href")), u.insertBefore(i, e), u.removeChild(e), i.media = e.media 34 | } 35 | }; 36 | // try { 37 | // p.open("GET", i), p.send(null) 38 | // } catch(t) { 39 | // "undefined" != typeof XDomainRequest && (p = new XDomainRequest, p.onerror = p.onprogress = function() {}, p.onload = n, p.open("GET", i), p.send(null)) 40 | // } 41 | e.setAttribute("data-inprogress", "") 42 | }, 43 | styleElement: function(e) { 44 | if(!e.hasAttribute("data-noprefix")) { 45 | var t = e.disabled; 46 | e.textContent = r.fix(e.textContent, !0, e), e.disabled = t 47 | } 48 | }, 49 | styleAttribute: function(e) { 50 | var t = e.getAttribute("style"); 51 | t = r.fix(t, !1, e), e.setAttribute("style", t) 52 | }, 53 | process: function() { 54 | e("style").forEach(StyleFix.styleElement), e("[style]").forEach(StyleFix.styleAttribute) 55 | }, 56 | register: function(e, t) { 57 | (r.fixers = r.fixers || []).splice(void 0 === t ? r.fixers.length : t, 0, e) 58 | }, 59 | fix: function(e, t, n) { 60 | for(var i = 0; i < r.fixers.length; i++) e = r.fixers[i](e, t, n) || e; 61 | return e 62 | }, 63 | camelCase: function(e) { 64 | return e.replace(/-([a-z])/g, function(e, r) { 65 | return r.toUpperCase() 66 | }).replace("-", "") 67 | }, 68 | deCamelCase: function(e) { 69 | return e.replace(/[A-Z]/g, function(e) { 70 | return "-" + e.toLowerCase() 71 | }) 72 | } 73 | }; 74 | ! function() { 75 | setTimeout(function() {}, 10), document.addEventListener("DOMContentLoaded", StyleFix.process, !1) 76 | }() 77 | } 78 | }(), 79 | function(e) { 80 | function r(e, r, n, i, a) { 81 | if(e = t[e], e.length) { 82 | var o = RegExp(r + "(" + e.join("|") + ")" + n, "gi"); 83 | a = a.replace(o, i) 84 | } 85 | return a 86 | } 87 | if(window.StyleFix && window.getComputedStyle) { 88 | var t = window.PrefixFree = { 89 | prefixCSS: function(e, n) { 90 | var i = t.prefix; 91 | if(t.functions.indexOf("linear-gradient") > -1 && (e = e.replace(/(\s|:|,)(repeating-)?linear-gradient\(\s*(-?\d*\.?\d*)deg/gi, function(e, r, t, n) { 92 | return r + (t || "") + "linear-gradient(" + (90 - n) + "deg" 93 | })), e = r("functions", "(\\s|:|,)", "\\s*\\(", "$1" + i + "$2(", e), e = r("keywords", "(\\s|:)", "(\\s|;|\\}|$)", "$1" + i + "$2$3", e), e = r("properties", "(^|\\{|\\s|;)", "\\s*:", "$1" + i + "$2:", e), t.properties.length) { 94 | var a = RegExp("\\b(" + t.properties.join("|") + ")(?!:)", "gi"); 95 | e = r("valueProperties", "\\b", ":(.+?);", function(e) { 96 | return e.replace(a, i + "$1") 97 | }, e) 98 | } 99 | return n && (e = r("selectors", "", "\\b", t.prefixSelector, e), e = r("atrules", "@", "\\b", "@" + i + "$1", e)), e = e.replace(RegExp("-" + i, "g"), "-"), e = e.replace(/-\*-(?=[a-z]+)/gi, t.prefix) 100 | }, 101 | property: function(e) { 102 | return(t.properties.indexOf(e) ? t.prefix : "") + e 103 | }, 104 | value: function(e) { 105 | return e = r("functions", "(^|\\s|,)", "\\s*\\(", "$1" + t.prefix + "$2(", e), e = r("keywords", "(^|\\s)", "(\\s|$)", "$1" + t.prefix + "$2$3", e) 106 | }, 107 | prefixSelector: function(e) { 108 | return e.replace(/^:{1,2}/, function(e) { 109 | return e + t.prefix 110 | }) 111 | }, 112 | prefixProperty: function(e, r) { 113 | var n = t.prefix + e; 114 | return r ? StyleFix.camelCase(n) : n 115 | } 116 | }; 117 | ! function() { 118 | var e = {}, 119 | r = [], 120 | n = getComputedStyle(document.documentElement, null), 121 | i = document.createElement("div").style, 122 | a = function(t) { 123 | if("-" === t.charAt(0)) { 124 | r.push(t); 125 | var n = t.split("-"), 126 | i = n[1]; 127 | for(e[i] = ++e[i] || 1; n.length > 3;) { 128 | n.pop(); 129 | var a = n.join("-"); 130 | o(a) && -1 === r.indexOf(a) && r.push(a) 131 | } 132 | } 133 | }, 134 | o = function(e) { 135 | return StyleFix.camelCase(e) in i 136 | }; 137 | if(n.length > 0) 138 | for(var s = 0; s < n.length; s++) a(n[s]); 139 | else 140 | for(var l in n) a(StyleFix.deCamelCase(l)); 141 | var u = { 142 | uses: 0 143 | }; 144 | for(var p in e) { 145 | var f = e[p]; 146 | u.uses < f && (u = { 147 | prefix: p, 148 | uses: f 149 | }) 150 | } 151 | t.prefix = "-" + u.prefix + "-", t.Prefix = StyleFix.camelCase(t.prefix), t.properties = []; 152 | for(var s = 0; s < r.length; s++) { 153 | var l = r[s]; 154 | if(0 === l.indexOf(t.prefix)) { 155 | var c = l.slice(t.prefix.length); 156 | o(c) || t.properties.push(c) 157 | } 158 | } 159 | "Ms" != t.Prefix || "transform" in i || "MsTransform" in i || !("msTransform" in i) || t.properties.push("transform", "transform-origin"), t.properties.sort() 160 | }(), 161 | function() { 162 | function e(e, r) { 163 | return i[r] = "", i[r] = e, !!i[r] 164 | } 165 | var r = { 166 | "linear-gradient": { 167 | property: "backgroundImage", 168 | params: "red, teal" 169 | }, 170 | calc: { 171 | property: "width", 172 | params: "1px + 5%" 173 | }, 174 | element: { 175 | property: "backgroundImage", 176 | params: "#foo" 177 | }, 178 | "cross-fade": { 179 | property: "backgroundImage", 180 | params: "url(a.png), url(b.png), 50%" 181 | } 182 | }; 183 | r["repeating-linear-gradient"] = r["repeating-radial-gradient"] = r["radial-gradient"] = r["linear-gradient"]; 184 | var n = { 185 | initial: "color", 186 | "zoom-in": "cursor", 187 | "zoom-out": "cursor", 188 | box: "display", 189 | flexbox: "display", 190 | "inline-flexbox": "display", 191 | flex: "display", 192 | "inline-flex": "display", 193 | grid: "display", 194 | "inline-grid": "display", 195 | "min-content": "width" 196 | }; 197 | t.functions = [], t.keywords = []; 198 | var i = document.createElement("div").style; 199 | for(var a in r) { 200 | var o = r[a], 201 | s = o.property, 202 | l = a + "(" + o.params + ")"; 203 | !e(l, s) && e(t.prefix + l, s) && t.functions.push(a) 204 | } 205 | for(var u in n) { 206 | var s = n[u]; 207 | !e(u, s) && e(t.prefix + u, s) && t.keywords.push(u) 208 | } 209 | }(), 210 | function() { 211 | function r(e) { 212 | return a.textContent = e + "{}", !!a.sheet.cssRules.length 213 | } 214 | var n = { 215 | ":read-only": null, 216 | ":read-write": null, 217 | ":any-link": null, 218 | "::selection": null 219 | }, 220 | i = { 221 | keyframes: "name", 222 | viewport: null, 223 | document: 'regexp(".")' 224 | }; 225 | t.selectors = [], t.atrules = []; 226 | var a = e.appendChild(document.createElement("style")); 227 | for(var o in n) { 228 | var s = o + (n[o] ? "(" + n[o] + ")" : ""); 229 | !r(s) && r(t.prefixSelector(s)) && t.selectors.push(o) 230 | } 231 | for(var l in i) { 232 | var s = l + " " + (i[l] || ""); 233 | !r("@" + s) && r("@" + t.prefix + s) && t.atrules.push(l) 234 | } 235 | e.removeChild(a) 236 | }(), t.valueProperties = ["transition", "transition-property"], e.className += " " + t.prefix, StyleFix.register(t.prefixCSS) 237 | } 238 | }(document.documentElement); -------------------------------------------------------------------------------- /static/css/result.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | html { 3 | *overflow: auto; 4 | } 5 | 6 | #hd { 7 | padding: 20px 8.5%; 8 | background-color: #000000; 9 | } 10 | 11 | #bd { 12 | margin-bottom: 40px; 13 | width: 80%; 14 | margin: auto; 15 | } 16 | 17 | .logo { 18 | float: left; 19 | margin-right: 30px; 20 | height: 33px; 21 | } 22 | 23 | 24 | /*input搜索区域*/ 25 | 26 | .inputArea { 27 | float: left; 28 | position: relative; 29 | margin-left: 3.2%; 30 | padding-top: 5px; 31 | } 32 | 33 | .inputArea .searchInput { 34 | border: 1px solid #ffffff; 35 | padding: 0 15px; 36 | outline: none; 37 | height: 35px; 38 | *line-height: 35px; 39 | width: 350px; 40 | font-size: 14px; 41 | } 42 | 43 | .inputArea .searchButton { 44 | position: absolute; 45 | left: 382px; 46 | top: 0; 47 | *top: 1px; 48 | *left: 381px; 49 | width: 106px; 50 | height: 38px; 51 | background: url(../img/btn_min.png) no-repeat; 52 | border: none; 53 | cursor: pointer; 54 | } 55 | 56 | 57 | /*返回高级搜索*/ 58 | 59 | .inputArea .advanced { 60 | position: absolute; 61 | font-size: 14px; 62 | left: 500px; 63 | top: 12px; 64 | width: 60px; 65 | text-decoration: underline; 66 | } 67 | 68 | 69 | /*分界区域,导航*/ 70 | 71 | .nav { 72 | margin-bottom: 24px; 73 | height: 31px; 74 | background: #f9f9f9; 75 | border-bottom: 1px solid #e0e0e0; 76 | padding: 5px 0 0 210px; 77 | } 78 | 79 | .searchList { 80 | float: left; 81 | padding-left: 10%; 82 | } 83 | 84 | .searchList .searchItem { 85 | float: left; 86 | margin-right: 15px; 87 | font-size: 14px; 88 | padding: 0 3px 2px 3px; 89 | cursor: pointer; 90 | height: 26px; 91 | line-height: 26px; 92 | } 93 | 94 | .searchList .searchItem.current { 95 | color: #0080cc; 96 | border-bottom: 3px solid #9cc813; 97 | font-weight: bold; 98 | } 99 | 100 | .nav .tips { 101 | color: #969696; 102 | font-size: 12px; 103 | line-height: 24px; 104 | *line-height: 26px; 105 | } 106 | 107 | #container.sideBarHide .nav { 108 | padding-left: 35px; 109 | } 110 | 111 | 112 | /*#main区域样式*/ 113 | 114 | #main { 115 | padding: 0 215px 0 182px; 116 | } 117 | 118 | #main.sideBarHide { 119 | padding-left: 10px; 120 | } 121 | 122 | 123 | /*侧边栏搜索条件*/ 124 | 125 | .sideBar { 126 | position: relative; 127 | float: left; 128 | margin-left: -182px; 129 | width: 182px; 130 | font-size: 16px; 131 | } 132 | 133 | .sideBar .subfieldContext { 134 | margin-bottom: 20px; 135 | padding-left: 25px; 136 | } 137 | 138 | .sideBar .subfieldContext li { 139 | margin-bottom: 5px; 140 | cursor: pointer; 141 | } 142 | 143 | .sideBar .subfieldContext input[type=text] { 144 | width: 75px; 145 | } 146 | 147 | .sideBar .unit { 148 | color: #787878; 149 | } 150 | 151 | 152 | /*更多按钮*/ 153 | 154 | .sideBar .more a:hover { 155 | text-decoration: none; 156 | } 157 | 158 | .sideBar .more .moreIcon { 159 | display: inline-block; 160 | position: relative; 161 | top: -1px; 162 | *top: -3px; 163 | left: 2px; 164 | *left: -1px; 165 | width: 9px; 166 | height: 5px; 167 | background: url(../img/more.png); 168 | } 169 | 170 | .sideBar .more.show .moreIcon { 171 | background: url(../img/down.png); 172 | top: -2px; 173 | } 174 | 175 | .sideBar .reset { 176 | padding-left: 25px; 177 | } 178 | 179 | 180 | /*siderBar区域显隐控制*/ 181 | 182 | .sideBar .sideBarShowHide { 183 | position: absolute; 184 | right: 0px; 185 | top: 20px; 186 | height: 177px; 187 | width: 1px; 188 | background: url(../img/line.png) right; 189 | } 190 | 191 | .sideBar .sideBarShowHide a { 192 | position: absolute; 193 | top: 70px; 194 | left: -11px; 195 | display: inline-block; 196 | width: 12px; 197 | height: 31px; 198 | background: url(../img/lr.png); 199 | } 200 | 201 | .sideBar .sideBarShowHide a:hover { 202 | background-position: 0 -31px; 203 | } 204 | 205 | 206 | /*左侧收起样式*/ 207 | 208 | #main.sideBarHide .sideBar { 209 | margin-left: -191px; 210 | *margin-left: -182px; 211 | } 212 | 213 | #main.sideBarHide .sideBar .sideBarShowHide { 214 | -moz-transform: rotate(180deg); 215 | -o-transform: rotate(180deg); 216 | -webkit-transform: rotate(180deg); 217 | transform: rotate(180deg); 218 | } 219 | 220 | #main.sideBarHide .sideBar .sideBarShowHide a { 221 | *background: url(../img/ll.png); 222 | } 223 | 224 | #main.sideBarHide .sideBar .sideBarShowHide a:hover { 225 | *background-position: 0 -31px; 226 | } 227 | 228 | #main.sideBarHide .sideBar .sideBarShowHide { 229 | background: none; 230 | } 231 | 232 | .resultArea { 233 | float: left; 234 | width: 100%; 235 | } 236 | 237 | .resultArea .resultTotal { 238 | position: relative; 239 | padding-left: 30px; 240 | margin-bottom: 20px; 241 | } 242 | 243 | .resultArea .resultTotal .info { 244 | color: #9a9a9a; 245 | } 246 | 247 | .resultArea .resultTotal .orderOpt { 248 | position: absolute; 249 | right: 50px; 250 | } 251 | 252 | .resultArea .resultTotal .orderOpt a { 253 | margin-right: 10px; 254 | color: #0080cc; 255 | } 256 | 257 | 258 | /*搜索结果列表区域*/ 259 | 260 | .resultArea .resultList { 261 | padding-left: 30px; 262 | } 263 | 264 | .resultArea .resultList .resultItem { 265 | margin-bottom: 20px; 266 | } 267 | 268 | .resultArea .resultList .resultItem { 269 | margin-bottom: 30px; 270 | } 271 | 272 | .resultArea .resultList .itemHead { 273 | margin-bottom: 5px; 274 | color: #767676; 275 | } 276 | 277 | .resultArea .resultList .itemHead .keyWord { 278 | color: #d90909; 279 | } 280 | 281 | .resultArea .resultList .itemBody .keyWord { 282 | color: #d90909; 283 | } 284 | 285 | .resultArea .resultList .itemHead a.title { 286 | font-size: 18px; 287 | color: #0080cc; 288 | text-decoration: underline; 289 | } 290 | 291 | .resultArea .resultList .itemHead .value { 292 | color: #008000; 293 | } 294 | 295 | .resultArea .resultList .itemHead .divsion { 296 | margin: 0 5px; 297 | } 298 | 299 | .resultArea .resultList .itemHead .fileType { 300 | margin-right: 10px; 301 | } 302 | 303 | 304 | /*搜索内容主体*/ 305 | 306 | .resultArea .resultList .itemBody { 307 | margin-bottom: 5px; 308 | line-height: 18px; 309 | width: 90%; 310 | font-size: 14px; 311 | } 312 | 313 | .resultArea .resultList .itemFoot { 314 | color: #008000; 315 | } 316 | 317 | .resultArea .resultList .itemFoot .info { 318 | margin-right: 10px; 319 | } 320 | 321 | .resultArea .pagination { 322 | margin-bottom: 25px; 323 | padding-left: 32px; 324 | } 325 | 326 | 327 | /*相关搜索*/ 328 | 329 | .resultArea .dependSearch { 330 | margin-bottom: 30px; 331 | padding-left: 32px; 332 | font-size: 14px; 333 | } 334 | 335 | .resultArea .dependSearch h6 { 336 | float: left; 337 | margin-right: 15px; 338 | font-weight: bold; 339 | } 340 | 341 | .resultArea .dependSearch p { 342 | margin-bottom: 5px; 343 | } 344 | 345 | .resultArea .dependSearch a { 346 | display: inline-block; 347 | margin-right: 15px; 348 | text-decoration: underline; 349 | width: 90px; 350 | white-space: nowrap; 351 | overflow: hidden; 352 | text-overflow: ellipsis; 353 | } 354 | 355 | .resultArea .searchInResult { 356 | padding-left: 35px; 357 | } 358 | 359 | .resultArea .searchInResult .inResult { 360 | position: absolute; 361 | right: -190px; 362 | top: 8px; 363 | font-size: 14px; 364 | text-decoration: underline; 365 | } 366 | 367 | .resultArea .searchInResult .searchButton { 368 | left: 417px; 369 | } 370 | 371 | 372 | /*历史搜索区域*/ 373 | 374 | .historyArea { 375 | float: right; 376 | margin-right: -212px; 377 | width: 212px; 378 | } 379 | 380 | .historyArea h6 { 381 | margin-bottom: 10px; 382 | font-weight: bold; 383 | } 384 | 385 | .historyArea .historyList { 386 | margin-bottom: 20px; 387 | } 388 | 389 | .historyArea .historyList li { 390 | margin-bottom: 5px; 391 | } 392 | 393 | 394 | /*左侧分栏区域*/ 395 | 396 | .subfield { 397 | margin-bottom: 5px; 398 | font-size: 14px; 399 | font-weight: bold; 400 | padding: 2px 0 2px 24px; 401 | } 402 | 403 | .subfield:first-child { 404 | border-left: 4px solid #9cc813; 405 | padding-left: 20px; 406 | } 407 | 408 | 409 | /*立即搜索样式*/ 410 | 411 | .subfieldContent .search { 412 | margin: 45px 0 0 135px; 413 | width: 130px; 414 | height: 36px; 415 | background: url(../img/btnbg.png); 416 | font-weight: bold; 417 | border: none; 418 | border: 1px solid #bfbfbf; 419 | line-height: 36px; 420 | } 421 | 422 | 423 | /*联想下拉区域*/ 424 | 425 | .inputArea .dataList { 426 | display: none; 427 | position: absolute; 428 | left: 0; 429 | top: 42px; 430 | *top: 43px; 431 | width: 550px; 432 | padding: 5px 0; 433 | background: #fff; 434 | border: 1px solid #bfbfbf; 435 | border-top: none; 436 | } 437 | 438 | .inputArea .dataList li { 439 | padding: 2px 15px; 440 | font-size: 14px; 441 | } 442 | 443 | .inputArea .dataList li:hover { 444 | background: #f0f0f0; 445 | color: #0080cc; 446 | font-weight: bold; 447 | } 448 | 449 | .inputArea input { 450 | padding: 0 34px 0 14px; 451 | height: 100%; 452 | width: 100%; 453 | border: 1px solid #e0e4e5; 454 | border-radius: 18px; 455 | outline: none; 456 | background: transparent; 457 | color: #e0e4e5 458 | } 459 | 460 | .inputArea img { 461 | position: absolute; 462 | width: 18px; 463 | height: 18px; 464 | right: 12px; 465 | top: 15px 466 | } 467 | 468 | .large { 469 | margin: 5px auto 10px auto; 470 | font-size: 1.5rem; 471 | text-align: center; 472 | text-transform: uppercase; 473 | color: #ffffff; 474 | } -------------------------------------------------------------------------------- /templates/result.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | TT-search搜索引擎 9 | 10 | 11 | 12 | 13 | 14 |
15 |
16 | 17 |
18 | 19 | search 20 | 21 |
22 |
23 | 34 |
35 |
36 | 69 |
70 |

71 | 找到约 {{ total_nums }} 条结果(用时{{ last_seconds }}秒),共约{{ page_nums }} 72 |

73 |
74 | 75 | {% for hit in all_hits %} 76 |
77 |
78 | {{ hit.title | safe }} 79 | - 80 | 81 | 来源: 82 | {{ hit.origin }} 83 | 84 | 85 | 得分: 86 | {{ hit.score }} 87 | 88 |
89 |
90 | {{ hit.content | safe}} 91 |
92 |
93 | 94 | 95 | {{ hit.url }} 96 | 97 | 98 | 99 | {{ hit.create_date }} 100 | 101 |
102 |
103 | {% endfor %} 104 |
105 | 106 | 107 | 108 | 109 | 110 | 111 |
112 |
113 |
114 | 115 |
116 |
117 | 118 |
119 |
120 |
121 |
122 |
123 | 124 | 125 | 126 | 127 | 128 | 129 | 199 | 219 | 276 | -------------------------------------------------------------------------------- /templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | TT-search 搜索引擎 9 | 10 | 11 | 12 | 13 | 14 | 15 | 35 | 36 | 37 |
38 |
39 |
40 |
41 |
42 |

43 | 46 |

47 | 55 |
56 | 57 | search 58 |
    59 | 60 |
61 |
62 |
63 |
64 | 65 |
66 |
67 | 68 |
69 |
70 |
71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 213 | 274 | 333 | -------------------------------------------------------------------------------- /common.py: -------------------------------------------------------------------------------- 1 | from moudels import Article_4houType,Article_anquankeType,Article_freebuf 2 | from config import client 3 | from datetime import datetime 4 | import re 5 | 6 | class elasticsearch_search(object): 7 | def __init__(self,type): 8 | self.s = type.search() 9 | if Article_anquankeType == type: 10 | self.index = "article_anquanke" 11 | elif Article_4houType == type: 12 | self.index = "teachnical_4hou" 13 | elif Article_freebuf == type: 14 | self.index = "teachnical_freebuf" 15 | 16 | def return_fuzzing_search(self,key_words): 17 | """ 18 | 模糊查询,分词匹配 19 | :param key_words: 20 | :return:re_dates 21 | """ 22 | re_dates = [] 23 | if key_words: 24 | s = self.s.suggest("my_suggest", key_words, completion={ 25 | "field": "suggest", 26 | "fuzzy": { 27 | "fuzziness": 2 28 | }, 29 | "size": 10 30 | }) 31 | suggestions = s.execute_suggest() 32 | for match in suggestions.my_suggest[0].options: 33 | source = match._source 34 | re_dates.append(source["title"]) 35 | return re_dates 36 | 37 | def get_date(self,key_words,page): 38 | """ 39 | 从elasticsearch中获取数据 40 | :param key_words: 41 | :param page: 42 | :return: response 43 | :return : last_seconds 44 | """ 45 | start_time = datetime.now() 46 | response = client.search( 47 | index = self.index, 48 | body = { 49 | "query":{ 50 | "multi_match":{ 51 | "query":key_words, 52 | "fields":["tags","title","content"] 53 | } 54 | }, 55 | "from":(page-1)*12, 56 | "size":12, 57 | "highlight":{ 58 | "pre_tags":[''], 59 | "post_tags":[''], 60 | "fields":{ 61 | "title":{}, 62 | "content":{}, 63 | } 64 | } 65 | } 66 | ) 67 | end_time = datetime.now() 68 | last_seconds = (end_time - start_time).total_seconds() 69 | return response,last_seconds 70 | 71 | def analyze_date(self,key_words,response): 72 | """ 73 | 返回分析后的数据列表集合 74 | :return:hit_list 75 | """ 76 | hit_list = [] 77 | for hit in response["hits"]["hits"]: 78 | hit_dict = {} 79 | hit_dict["origin"] = self.get_origin(hit) 80 | if "highlight" in hit: 81 | if "title" in hit["highlight"]: 82 | hit_dict["title"] = "".join(hit["highlight"]["title"]) 83 | else: 84 | hit_dict["title"] = hit["_source"]["title"] 85 | if "content" in hit["highlight"]: 86 | hit_dict["content"] = self.filter_tags("".join(hit["highlight"]["content"])) 87 | hit_dict["content"] = hit_dict["content"][:500]+">" 88 | #hit_dict["content"] = hit_dict["content"][:500] 89 | else: 90 | hit_dict["content"] = self.filter_tags(hit["_source"]["content"]) 91 | hit_dict["content"] = hit_dict["content"][:500]+">" 92 | #hit_dict["content"] = hit_dict["content"][:500] 93 | else: 94 | hit_dict["title"] = hit["_source"]["title"] 95 | hit_dict["content"] = self.filter_tags(hit["_source"]["content"][:500]) 96 | hit_dict["create_date"] = hit["_source"]["create_time"] 97 | hit_dict["url"] = hit["_source"]["url"] 98 | hit_dict["score"] = hit["_score"] 99 | replace_text = '' + key_words + "" 100 | words = "(?i)"+key_words 101 | hit_dict["content"] = re.sub(words,replace_text,hit_dict["content"]) 102 | hit_list.append(hit_dict) 103 | return hit_list 104 | 105 | def get_origin(self,hit): 106 | """ 107 | 获取文章来源 108 | :return:index_name 来源名称 109 | """ 110 | if "_index" in hit: 111 | if "teachnical_4hou" == hit["_index"]: 112 | origin = "嘶吼" 113 | elif "article_anquanke" == hit["_index"]: 114 | origin = "安全客" 115 | elif "teachnical_freebuf" == hit["_index"]: 116 | origin = "Freebuf" 117 | else: 118 | origin = "未知来源" 119 | return origin 120 | def filter_tags(self,htmlstr): 121 | """ 122 | 过滤HTML中的标签 123 | 将HTML中标签等信息去掉 124 | :param htmlstr: HTML字符串 125 | :return: 126 | """ 127 | # 先过滤CDATA 128 | re_cdata = re.compile('//]*//\]\]>', re.I) # 匹配CDATA 129 | re_script = re.compile('<\s*script[^>]*>[^<]*<\s*/\s*script\s*>', re.I) # Script 130 | re_style = re.compile('<\s*style[^>]*>[^<]*<\s*/\s*style\s*>', re.I) # style 131 | re_br = re.compile('') # 处理换行 132 | re_h = re.compile(']*>') # HTML标签 133 | re_comment = re.compile('') # HTML注释 134 | re_stopwords = re.compile('\u3000') # 去除无用的'\u3000'字符 135 | s = re_cdata.sub('', htmlstr) # 去掉CDATA 136 | s = re_script.sub('', s) # 去掉SCRIPT 137 | s = re_style.sub('', s) # 去掉style 138 | s = re_br.sub('\n', s) # 将br转换为换行 139 | s = re_h.sub('', s) # 去掉HTML 标签 140 | s = re_comment.sub('', s) # 去掉HTML注释 141 | s = re_stopwords.sub('', s) 142 | # 去掉多余的空行 143 | blank_line = re.compile('\n+') 144 | s = blank_line.sub('\n', s) 145 | s = self.replaceCharEntity(s) # 替换实体 146 | return s 147 | 148 | def replaceCharEntity(self,htmlstr): 149 | """ 150 | #替换常用HTML字符实体. 151 | 使用正常的字符替换HTML中特殊的字符实体. 152 | 你可以添加新的实体字符到CHAR_ENTITIES中,处理更多HTML字符实体. 153 | :param htmlstr: HTML字符串 154 | :return: 这个return不重要 155 | """ 156 | CHAR_ENTITIES = {'nbsp': ' ', '160': ' ', 157 | 'lt': '<', '60': '<', 158 | 'gt': '>', '62': '>', 159 | 'amp': '&', '38': '&', 160 | 'quot': '"', '34': '"', } 161 | 162 | re_charEntity = re.compile(r'&#?(?P\w+);') 163 | sz = re_charEntity.search(htmlstr) 164 | while sz: 165 | entity = sz.group() # entity全称,如> 166 | key = sz.group('name') # 去除&;后entity,如>为gt 167 | try: 168 | htmlstr = re_charEntity.sub(CHAR_ENTITIES[key], htmlstr, 1) 169 | sz = re_charEntity.search(htmlstr) 170 | except KeyError: 171 | # 以空串代替 172 | htmlstr = re_charEntity.sub('', htmlstr, 1) 173 | sz = re_charEntity.search(htmlstr) 174 | return htmlstr 175 | 176 | class elasticsearch_allsearch(elasticsearch_search): 177 | def __init__(self): 178 | self.s_a4hou = Article_4houType.search() 179 | self.s_anquanke = Article_anquankeType.search() 180 | self.s_freebuf = Article_freebuf.search() 181 | self.all_hits = [] 182 | 183 | def return_fuzzing_search(self,key_words): 184 | re_dates = [] 185 | if key_words: 186 | s_4hou = self.s_a4hou.suggest("my_suggest", key_words, completion={ 187 | "field": "suggest", 188 | "fuzzy": { 189 | "fuzziness": 2 190 | }, 191 | "size": 4 192 | }) 193 | suggestions_4hou = s_4hou.execute_suggest() 194 | 195 | for match_4hou in suggestions_4hou.my_suggest[0].options: 196 | source_4hou = match_4hou._source 197 | re_dates.append(source_4hou["title"]) 198 | s_anquanke = self.s_anquanke.suggest("my_suggest", key_words, completion={ 199 | "field": "suggest", 200 | "fuzzy": { 201 | "fuzziness": 2 202 | }, 203 | "size": 4 204 | }) 205 | 206 | suggestions_anquanke = s_anquanke.execute_suggest() 207 | 208 | for match_anquanke in suggestions_anquanke.my_suggest[0].options: 209 | source_anquanke = match_anquanke._source 210 | re_dates.append(source_anquanke["title"]) 211 | 212 | s_freebuf = self.s_freebuf.suggest("my_suggest",key_words,completion={ 213 | "field": "suggest", 214 | "fuzzy": { 215 | "fuzziness": 2 216 | }, 217 | "size": 12 - len(re_dates) 218 | }) 219 | suggestions_freebuf = s_freebuf.execute_suggest() 220 | 221 | for match_freebuf in suggestions_freebuf.my_suggest[0].options: 222 | source_freebuf = match_freebuf._source 223 | re_dates.append(source_freebuf["title"]) 224 | 225 | return re_dates 226 | 227 | 228 | 229 | def return_datenum(self,key_words,page=1): 230 | #获取数据条数 231 | self.index = "teachnical_4hou" 232 | response_4hou ,times = self.get_date(key_words,init=0,size=1) 233 | self.index = "article_anquanke" 234 | response_anquanke,times = self.get_date(key_words,init=0,size=1) 235 | self.index = "teachnical_freebuf" 236 | response_freebuf,times = self.get_date(key_words,init=0,size=1) 237 | total_nums_4hou = response_4hou["hits"]["total"] 238 | total_nums_anquanke = response_anquanke["hits"]["total"] 239 | total_nums_freebuf = response_freebuf["hits"]["total"] 240 | zipmin= min(total_nums_4hou,total_nums_anquanke,total_nums_freebuf) 241 | #获取数据个数处理 242 | response_and_time_list = self.get_zipdate(zipmin,total_nums_4hou,total_nums_anquanke,total_nums_freebuf,key_words,page,size=4) 243 | #对获取到的数据进行处理 244 | for response in response_and_time_list[:-1]: 245 | datalist = super().analyze_date(key_words,response) 246 | self.all_hits = self.all_hits + datalist 247 | last_seconds = response_and_time_list[-1] 248 | return self.all_hits,last_seconds,total_nums_4hou+total_nums_anquanke+total_nums_freebuf 249 | 250 | def get_zipdate(self,zipmin,nums_4hou,nums_anquanke,nums_freebuf,key_words,page,size): 251 | """ 252 | :return: 253 | """ 254 | init = (page - 1) * size 255 | if init <= zipmin: 256 | self.index = "teachnical_4hou" 257 | response_4hou,time_4hou = self.get_date(key_words, init, size) 258 | self.index = "article_anquanke" 259 | response_anquanke,time_anquanke = self.get_date(key_words, init, size) 260 | self.index = "teachnical_freebuf" 261 | response_freebuf,time_freebuf = self.get_date(key_words, init, size) 262 | else : 263 | if init >= nums_4hou and init>=nums_anquanke: 264 | self.index = "teachnical_freebuf" 265 | init = int(init/3) + (page - 1 ) * size 266 | size = 12 267 | response_freebuf,time_freebuf = self.get_date(key_words,init,size) 268 | return response_freebuf,time_freebuf 269 | elif init >= nums_anquanke and init>= nums_freebuf: 270 | self.index = "teachnical_4hou" 271 | init = int(init / 3) + (page - 1) * size 272 | size = 12 273 | response_4hou, time_4hou = self.get_date(key_words, init, size) 274 | return response_4hou, time_4hou 275 | elif init >= nums_4hou and init >= nums_freebuf: 276 | self.index = "article_anquanke" 277 | init = int(init / 3) + (page - 1) * size 278 | size = 12 279 | response_anquanke, time_anquanke = self.get_date(key_words, init, size) 280 | return response_anquanke, time_anquanke 281 | elif init >= nums_4hou: 282 | self.index = "article_anquanke" 283 | init = int(init / 3) + (page - 1) * size 284 | size = 6 285 | response_anquanke, time_anquanke = self.get_date(key_words, init, size) 286 | self.index = "teachnical_freebuf" 287 | init = int(init / 3) + (page - 1) * size 288 | size = 12 289 | response_freebuf, time_freebuf = self.get_date(key_words, init, size) 290 | last_seconds = time_anquanke + time_freebuf 291 | return [response_anquanke, response_freebuf, last_seconds] 292 | elif init>=nums_freebuf: 293 | self.index = "article_anquanke" 294 | init = int(init / 3) + (page - 1) * size 295 | size = 6 296 | response_anquanke, time_anquanke = self.get_date(key_words, init, size) 297 | self.index = "teachnical_4hou" 298 | init = int(init / 3) + (page - 1) * size 299 | size = 12 300 | response_4hou, time_4hou = self.get_date(key_words, init, size) 301 | last_seconds = time_4hou + time_anquanke 302 | return [response_anquanke, response_4hou, last_seconds] 303 | elif init>=nums_anquanke: 304 | self.index = "teachnical_freebuf" 305 | init = int(init / 3) + (page - 1) * size 306 | size = 12 307 | response_freebuf, time_freebuf = self.get_date(key_words, init, size) 308 | self.index = "teachnical_4hou" 309 | init = int(init / 3) + (page - 1) * size 310 | size = 12 311 | response_4hou, time_4hou = self.get_date(key_words, init, size) 312 | last_seconds = time_4hou+ time_freebuf 313 | return [response_4hou, response_freebuf, last_seconds] 314 | 315 | """ 316 | if init >= nums_4hou: 317 | self.index = "article_anquanke" 318 | #init要变 319 | init = int(init/2) + (page - 1) * 5 320 | size = 10 321 | response_anquanke,time_anquanke = self.get_date(key_words,init,size) 322 | return response_anquanke,time_anquanke 323 | elif init >= nums_anquanke: 324 | self.index = "article_anquanke" 325 | init = int(init / 2) + (page - 1) * 5 326 | size = 10 327 | response_4hou,time_4hou = self.get_date(key_words,init,size) 328 | return response_4hou,time_4hou 329 | """ 330 | last_seconds = time_4hou + time_anquanke + time_freebuf 331 | return [response_anquanke,response_4hou,response_freebuf,last_seconds] 332 | 333 | 334 | 335 | 336 | 337 | def get_date(self,key_words,init,size): 338 | """ 339 | 从elasticsearch中获取数据 340 | :param key_words: 341 | :param page: 342 | :return: response 343 | :return : last_seconds 344 | """ 345 | start_time = datetime.now() 346 | response = client.search( 347 | index = self.index, 348 | body = { 349 | "query":{ 350 | "multi_match":{ 351 | "query":key_words, 352 | "fields":["tags","title","content"] 353 | } 354 | }, 355 | "from":init, 356 | "size":size, 357 | "highlight":{ 358 | "pre_tags":[''], 359 | "post_tags":[''], 360 | "fields":{ 361 | "title":{}, 362 | "content":{}, 363 | } 364 | } 365 | } 366 | ) 367 | end_time = datetime.now() 368 | last_seconds = (end_time - start_time).total_seconds() 369 | return response,last_seconds 370 | 371 | class get_elasticsearch_data_count(object): 372 | 373 | def __init__(self): 374 | self.index = [] 375 | self.counts = [] 376 | self.index.append("article_anquanke") 377 | self.index.append("teachnical_4hou") 378 | self.index.append("teachnical_freebuf") 379 | 380 | for index in self.index: 381 | count = self.__get_datecount(index) 382 | self.counts.append(count) 383 | 384 | self.counts.append(self.counts[0]+self.counts[1]+self.counts[2]) 385 | 386 | 387 | def __get_datecount(self,index): 388 | """ 389 | 获取数据总数 390 | :param index: 391 | :return:response["count"]当前索引数据总数 392 | """ 393 | response = client.count(index) 394 | return response["count"] 395 | 396 | def return_count(self): 397 | """ 398 | 用来返回数据 399 | :return: self.counts 返回数据列表 400 | """ 401 | return self.counts 402 | 403 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 103 | 104 | 105 | 106 | style.c 107 | dataList 108 | q= 109 | home-search-input 110 | keywo 111 | keyword 112 | 分页 113 | pageselectCallback 114 | pagi 115 | numPages 116 | current_page 117 | pageSelected 118 | getClickHandler 119 | page_id 120 | link_to 121 | opts 122 | s_type 123 | pagination.js 124 | add 125 | {{ page 126 | 127 | args 128 | 129 | 130 | 131 | 146 | 147 | 148 | 149 | 150 | true 151 | DEFINITION_ORDER 152 | 153 | 154 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | \n\n
\n\n Automatically save\n values to localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n', 1269 | ".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n", 1270 | dat.controllers.factory = function(e, a, c, d, f, b, n) { 1271 | return function(h, j, m, l) { 1272 | var o = h[j]; 1273 | if(n.isArray(m) || n.isObject(m)) return new e(h, j, m); 1274 | if(n.isNumber(o)) return n.isNumber(m) && n.isNumber(l) ? new c(h, j, m, l) : new a(h, j, { 1275 | min: m, 1276 | max: l 1277 | }); 1278 | if(n.isString(o)) return new d(h, j); 1279 | if(n.isFunction(o)) return new f(h, j, ""); 1280 | if(n.isBoolean(o)) return new b(h, j) 1281 | } 1282 | }(dat.controllers.OptionController, dat.controllers.NumberControllerBox, dat.controllers.NumberControllerSlider, dat.controllers.StringController = function(e, a, c) { 1283 | var d = 1284 | function(c, b) { 1285 | function e() { 1286 | h.setValue(h.__input.value) 1287 | } 1288 | d.superclass.call(this, c, b); 1289 | var h = this; 1290 | this.__input = document.createElement("input"); 1291 | this.__input.setAttribute("type", "text"); 1292 | a.bind(this.__input, "keyup", e); 1293 | a.bind(this.__input, "change", e); 1294 | a.bind(this.__input, "blur", function() { 1295 | h.__onFinishChange && h.__onFinishChange.call(h, h.getValue()) 1296 | }); 1297 | a.bind(this.__input, "keydown", function(a) { 1298 | a.keyCode === 13 && this.blur() 1299 | }); 1300 | this.updateDisplay(); 1301 | this.domElement.appendChild(this.__input) 1302 | }; 1303 | d.superclass = e; 1304 | c.extend(d.prototype, 1305 | e.prototype, { 1306 | updateDisplay: function() { 1307 | if(!a.isActive(this.__input)) this.__input.value = this.getValue(); 1308 | return d.superclass.prototype.updateDisplay.call(this) 1309 | } 1310 | }); 1311 | return d 1312 | }(dat.controllers.Controller, dat.dom.dom, dat.utils.common), dat.controllers.FunctionController, dat.controllers.BooleanController, dat.utils.common), dat.controllers.Controller, dat.controllers.BooleanController, dat.controllers.FunctionController, dat.controllers.NumberControllerBox, dat.controllers.NumberControllerSlider, dat.controllers.OptionController, 1313 | dat.controllers.ColorController = function(e, a, c, d, f) { 1314 | function b(a, b, c, d) { 1315 | a.style.background = ""; 1316 | f.each(j, function(e) { 1317 | a.style.cssText += "background: " + e + "linear-gradient(" + b + ", " + c + " 0%, " + d + " 100%); " 1318 | }) 1319 | } 1320 | 1321 | function n(a) { 1322 | a.style.background = ""; 1323 | a.style.cssText += "background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);"; 1324 | a.style.cssText += "background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"; 1325 | a.style.cssText += "background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"; 1326 | a.style.cssText += "background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"; 1327 | a.style.cssText += "background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);" 1328 | } 1329 | var h = function(e, l) { 1330 | function o(b) { 1331 | q(b); 1332 | a.bind(window, "mousemove", q); 1333 | a.bind(window, 1334 | "mouseup", j) 1335 | } 1336 | 1337 | function j() { 1338 | a.unbind(window, "mousemove", q); 1339 | a.unbind(window, "mouseup", j) 1340 | } 1341 | 1342 | function g() { 1343 | var a = d(this.value); 1344 | a !== false ? (p.__color.__state = a, p.setValue(p.__color.toOriginal())) : this.value = p.__color.toString() 1345 | } 1346 | 1347 | function i() { 1348 | a.unbind(window, "mousemove", s); 1349 | a.unbind(window, "mouseup", i) 1350 | } 1351 | 1352 | function q(b) { 1353 | b.preventDefault(); 1354 | var c = a.getWidth(p.__saturation_field), 1355 | d = a.getOffset(p.__saturation_field), 1356 | e = (b.clientX - d.left + document.body.scrollLeft) / c, 1357 | b = 1 - (b.clientY - d.top + document.body.scrollTop) / c; 1358 | b > 1 ? b = 1359 | 1 : b < 0 && (b = 0); 1360 | e > 1 ? e = 1 : e < 0 && (e = 0); 1361 | p.__color.v = b; 1362 | p.__color.s = e; 1363 | p.setValue(p.__color.toOriginal()); 1364 | return false 1365 | } 1366 | 1367 | function s(b) { 1368 | b.preventDefault(); 1369 | var c = a.getHeight(p.__hue_field), 1370 | d = a.getOffset(p.__hue_field), 1371 | b = 1 - (b.clientY - d.top + document.body.scrollTop) / c; 1372 | b > 1 ? b = 1 : b < 0 && (b = 0); 1373 | p.__color.h = b * 360; 1374 | p.setValue(p.__color.toOriginal()); 1375 | return false 1376 | } 1377 | h.superclass.call(this, e, l); 1378 | this.__color = new c(this.getValue()); 1379 | this.__temp = new c(0); 1380 | var p = this; 1381 | this.domElement = document.createElement("div"); 1382 | a.makeSelectable(this.domElement, 1383 | false); 1384 | this.__selector = document.createElement("div"); 1385 | this.__selector.className = "selector"; 1386 | this.__saturation_field = document.createElement("div"); 1387 | this.__saturation_field.className = "saturation-field"; 1388 | this.__field_knob = document.createElement("div"); 1389 | this.__field_knob.className = "field-knob"; 1390 | this.__field_knob_border = "2px solid "; 1391 | this.__hue_knob = document.createElement("div"); 1392 | this.__hue_knob.className = "hue-knob"; 1393 | this.__hue_field = document.createElement("div"); 1394 | this.__hue_field.className = "hue-field"; 1395 | this.__input = 1396 | document.createElement("input"); 1397 | this.__input.type = "text"; 1398 | this.__input_textShadow = "0 1px 1px "; 1399 | a.bind(this.__input, "keydown", function(a) { 1400 | a.keyCode === 13 && g.call(this) 1401 | }); 1402 | a.bind(this.__input, "blur", g); 1403 | a.bind(this.__selector, "mousedown", function() { 1404 | a.addClass(this, "drag").bind(window, "mouseup", function() { 1405 | a.removeClass(p.__selector, "drag") 1406 | }) 1407 | }); 1408 | var t = document.createElement("div"); 1409 | f.extend(this.__selector.style, { 1410 | width: "122px", 1411 | height: "102px", 1412 | padding: "3px", 1413 | backgroundColor: "#222", 1414 | boxShadow: "0px 1px 3px rgba(0,0,0,0.3)" 1415 | }); 1416 | f.extend(this.__field_knob.style, { 1417 | position: "absolute", 1418 | width: "12px", 1419 | height: "12px", 1420 | border: this.__field_knob_border + (this.__color.v < 0.5 ? "#fff" : "#000"), 1421 | boxShadow: "0px 1px 3px rgba(0,0,0,0.5)", 1422 | borderRadius: "12px", 1423 | zIndex: 1 1424 | }); 1425 | f.extend(this.__hue_knob.style, { 1426 | position: "absolute", 1427 | width: "15px", 1428 | height: "2px", 1429 | borderRight: "4px solid #fff", 1430 | zIndex: 1 1431 | }); 1432 | f.extend(this.__saturation_field.style, { 1433 | width: "100px", 1434 | height: "100px", 1435 | border: "1px solid #555", 1436 | marginRight: "3px", 1437 | display: "inline-block", 1438 | cursor: "pointer" 1439 | }); 1440 | f.extend(t.style, { 1441 | width: "100%", 1442 | height: "100%", 1443 | background: "none" 1444 | }); 1445 | b(t, "top", "rgba(0,0,0,0)", "#000"); 1446 | f.extend(this.__hue_field.style, { 1447 | width: "15px", 1448 | height: "100px", 1449 | display: "inline-block", 1450 | border: "1px solid #555", 1451 | cursor: "ns-resize" 1452 | }); 1453 | n(this.__hue_field); 1454 | f.extend(this.__input.style, { 1455 | outline: "none", 1456 | textAlign: "center", 1457 | color: "#fff", 1458 | border: 0, 1459 | fontWeight: "bold", 1460 | textShadow: this.__input_textShadow + "rgba(0,0,0,0.7)" 1461 | }); 1462 | a.bind(this.__saturation_field, "mousedown", o); 1463 | a.bind(this.__field_knob, "mousedown", o); 1464 | a.bind(this.__hue_field, "mousedown", 1465 | function(b) { 1466 | s(b); 1467 | a.bind(window, "mousemove", s); 1468 | a.bind(window, "mouseup", i) 1469 | }); 1470 | this.__saturation_field.appendChild(t); 1471 | this.__selector.appendChild(this.__field_knob); 1472 | this.__selector.appendChild(this.__saturation_field); 1473 | this.__selector.appendChild(this.__hue_field); 1474 | this.__hue_field.appendChild(this.__hue_knob); 1475 | this.domElement.appendChild(this.__input); 1476 | this.domElement.appendChild(this.__selector); 1477 | this.updateDisplay() 1478 | }; 1479 | h.superclass = e; 1480 | f.extend(h.prototype, e.prototype, { 1481 | updateDisplay: function() { 1482 | var a = d(this.getValue()); 1483 | if(a !== false) { 1484 | var e = false; 1485 | f.each(c.COMPONENTS, function(b) { 1486 | if(!f.isUndefined(a[b]) && !f.isUndefined(this.__color.__state[b]) && a[b] !== this.__color.__state[b]) return e = true, {} 1487 | }, this); 1488 | e && f.extend(this.__color.__state, a) 1489 | } 1490 | f.extend(this.__temp.__state, this.__color.__state); 1491 | this.__temp.a = 1; 1492 | var h = this.__color.v < 0.5 || this.__color.s > 0.5 ? 255 : 0, 1493 | j = 255 - h; 1494 | f.extend(this.__field_knob.style, { 1495 | marginLeft: 100 * this.__color.s - 7 + "px", 1496 | marginTop: 100 * (1 - this.__color.v) - 7 + "px", 1497 | backgroundColor: this.__temp.toString(), 1498 | border: this.__field_knob_border + 1499 | "rgb(" + h + "," + h + "," + h + ")" 1500 | }); 1501 | this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + "px"; 1502 | this.__temp.s = 1; 1503 | this.__temp.v = 1; 1504 | b(this.__saturation_field, "left", "#fff", this.__temp.toString()); 1505 | f.extend(this.__input.style, { 1506 | backgroundColor: this.__input.value = this.__color.toString(), 1507 | color: "rgb(" + h + "," + h + "," + h + ")", 1508 | textShadow: this.__input_textShadow + "rgba(" + j + "," + j + "," + j + ",.7)" 1509 | }) 1510 | } 1511 | }); 1512 | var j = ["-moz-", "-o-", "-webkit-", "-ms-", ""]; 1513 | return h 1514 | }(dat.controllers.Controller, dat.dom.dom, dat.color.Color = function(e, a, c, d) { 1515 | function f(a, 1516 | b, c) { 1517 | Object.defineProperty(a, b, { 1518 | get: function() { 1519 | if(this.__state.space === "RGB") return this.__state[b]; 1520 | n(this, b, c); 1521 | return this.__state[b] 1522 | }, 1523 | set: function(a) { 1524 | if(this.__state.space !== "RGB") n(this, b, c), this.__state.space = "RGB"; 1525 | this.__state[b] = a 1526 | } 1527 | }) 1528 | } 1529 | 1530 | function b(a, b) { 1531 | Object.defineProperty(a, b, { 1532 | get: function() { 1533 | if(this.__state.space === "HSV") return this.__state[b]; 1534 | h(this); 1535 | return this.__state[b] 1536 | }, 1537 | set: function(a) { 1538 | if(this.__state.space !== "HSV") h(this), this.__state.space = "HSV"; 1539 | this.__state[b] = a 1540 | } 1541 | }) 1542 | } 1543 | 1544 | function n(b, c, e) { 1545 | if(b.__state.space === 1546 | "HEX") b.__state[c] = a.component_from_hex(b.__state.hex, e); 1547 | else if(b.__state.space === "HSV") d.extend(b.__state, a.hsv_to_rgb(b.__state.h, b.__state.s, b.__state.v)); 1548 | else throw "Corrupted color state"; 1549 | } 1550 | 1551 | function h(b) { 1552 | var c = a.rgb_to_hsv(b.r, b.g, b.b); 1553 | d.extend(b.__state, { 1554 | s: c.s, 1555 | v: c.v 1556 | }); 1557 | if(d.isNaN(c.h)) { 1558 | if(d.isUndefined(b.__state.h)) b.__state.h = 0 1559 | } else b.__state.h = c.h 1560 | } 1561 | var j = function() { 1562 | this.__state = e.apply(this, arguments); 1563 | if(this.__state === false) throw "Failed to interpret color arguments"; 1564 | this.__state.a = this.__state.a || 1565 | 1 1566 | }; 1567 | j.COMPONENTS = "r,g,b,h,s,v,hex,a".split(","); 1568 | d.extend(j.prototype, { 1569 | toString: function() { 1570 | return c(this) 1571 | }, 1572 | toOriginal: function() { 1573 | return this.__state.conversion.write(this) 1574 | } 1575 | }); 1576 | f(j.prototype, "r", 2); 1577 | f(j.prototype, "g", 1); 1578 | f(j.prototype, "b", 0); 1579 | b(j.prototype, "h"); 1580 | b(j.prototype, "s"); 1581 | b(j.prototype, "v"); 1582 | Object.defineProperty(j.prototype, "a", { 1583 | get: function() { 1584 | return this.__state.a 1585 | }, 1586 | set: function(a) { 1587 | this.__state.a = a 1588 | } 1589 | }); 1590 | Object.defineProperty(j.prototype, "hex", { 1591 | get: function() { 1592 | if(!this.__state.space !== "HEX") this.__state.hex = 1593 | a.rgb_to_hex(this.r, this.g, this.b); 1594 | return this.__state.hex 1595 | }, 1596 | set: function(a) { 1597 | this.__state.space = "HEX"; 1598 | this.__state.hex = a 1599 | } 1600 | }); 1601 | return j 1602 | }(dat.color.interpret, dat.color.math = function() { 1603 | var e; 1604 | return { 1605 | hsv_to_rgb: function(a, c, d) { 1606 | var e = a / 60 - Math.floor(a / 60), 1607 | b = d * (1 - c), 1608 | n = d * (1 - e * c), 1609 | c = d * (1 - (1 - e) * c), 1610 | a = [ 1611 | [d, c, b], 1612 | [n, d, b], 1613 | [b, d, c], 1614 | [b, n, d], 1615 | [c, b, d], 1616 | [d, b, n] 1617 | ][Math.floor(a / 60) % 6]; 1618 | return { 1619 | r: a[0] * 255, 1620 | g: a[1] * 255, 1621 | b: a[2] * 255 1622 | } 1623 | }, 1624 | rgb_to_hsv: function(a, c, d) { 1625 | var e = Math.min(a, c, d), 1626 | b = Math.max(a, c, d), 1627 | e = b - e; 1628 | if(b == 0) return { 1629 | h: NaN, 1630 | s: 0, 1631 | v: 0 1632 | }; 1633 | a = a == b ? (c - d) / e : c == b ? 2 + (d - a) / e : 4 + (a - c) / e; 1634 | a /= 6; 1635 | a < 0 && (a += 1); 1636 | return { 1637 | h: a * 360, 1638 | s: e / b, 1639 | v: b / 255 1640 | } 1641 | }, 1642 | rgb_to_hex: function(a, c, d) { 1643 | a = this.hex_with_component(0, 2, a); 1644 | a = this.hex_with_component(a, 1, c); 1645 | return a = this.hex_with_component(a, 0, d) 1646 | }, 1647 | component_from_hex: function(a, c) { 1648 | return a >> c * 8 & 255 1649 | }, 1650 | hex_with_component: function(a, c, d) { 1651 | return d << (e = c * 8) | a & ~(255 << e) 1652 | } 1653 | } 1654 | }(), dat.color.toString, dat.utils.common), dat.color.interpret, dat.utils.common), dat.utils.requestAnimationFrame = function() { 1655 | return window.webkitRequestAnimationFrame || 1656 | window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(e) { 1657 | window.setTimeout(e, 1E3 / 60) 1658 | } 1659 | }(), dat.dom.CenteredDiv = function(e, a) { 1660 | var c = function() { 1661 | this.backgroundElement = document.createElement("div"); 1662 | a.extend(this.backgroundElement.style, { 1663 | backgroundColor: "rgba(0,0,0,0.8)", 1664 | top: 0, 1665 | left: 0, 1666 | display: "none", 1667 | zIndex: "1000", 1668 | opacity: 0, 1669 | WebkitTransition: "opacity 0.2s linear" 1670 | }); 1671 | e.makeFullscreen(this.backgroundElement); 1672 | this.backgroundElement.style.position = "fixed"; 1673 | this.domElement = 1674 | document.createElement("div"); 1675 | a.extend(this.domElement.style, { 1676 | position: "fixed", 1677 | display: "none", 1678 | zIndex: "1001", 1679 | opacity: 0, 1680 | WebkitTransition: "-webkit-transform 0.2s ease-out, opacity 0.2s linear" 1681 | }); 1682 | document.body.appendChild(this.backgroundElement); 1683 | document.body.appendChild(this.domElement); 1684 | var c = this; 1685 | e.bind(this.backgroundElement, "click", function() { 1686 | c.hide() 1687 | }) 1688 | }; 1689 | c.prototype.show = function() { 1690 | var c = this; 1691 | this.backgroundElement.style.display = "block"; 1692 | this.domElement.style.display = "block"; 1693 | this.domElement.style.opacity = 1694 | 0; 1695 | this.domElement.style.webkitTransform = "scale(1.1)"; 1696 | this.layout(); 1697 | a.defer(function() { 1698 | c.backgroundElement.style.opacity = 1; 1699 | c.domElement.style.opacity = 1; 1700 | c.domElement.style.webkitTransform = "scale(1)" 1701 | }) 1702 | }; 1703 | c.prototype.hide = function() { 1704 | var a = this, 1705 | c = function() { 1706 | a.domElement.style.display = "none"; 1707 | a.backgroundElement.style.display = "none"; 1708 | e.unbind(a.domElement, "webkitTransitionEnd", c); 1709 | e.unbind(a.domElement, "transitionend", c); 1710 | e.unbind(a.domElement, "oTransitionEnd", c) 1711 | }; 1712 | e.bind(this.domElement, "webkitTransitionEnd", 1713 | c); 1714 | e.bind(this.domElement, "transitionend", c); 1715 | e.bind(this.domElement, "oTransitionEnd", c); 1716 | this.backgroundElement.style.opacity = 0; 1717 | this.domElement.style.opacity = 0; 1718 | this.domElement.style.webkitTransform = "scale(1.1)" 1719 | }; 1720 | c.prototype.layout = function() { 1721 | this.domElement.style.left = window.innerWidth / 2 - e.getWidth(this.domElement) / 2 + "px"; 1722 | this.domElement.style.top = window.innerHeight / 2 - e.getHeight(this.domElement) / 2 + "px" 1723 | }; 1724 | return c 1725 | }(dat.dom.dom, dat.utils.common), dat.dom.dom, dat.utils.common); --------------------------------------------------------------------------------