├── .gitignore ├── .idea ├── hackdelft.iml ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml ├── modules.xml ├── vcs.xml └── workspace.xml ├── README.md └── hackdelft ├── .gitignore ├── .idea ├── hackdelft.iml ├── inspectionProfiles │ └── profiles_settings.xml ├── misc.xml └── modules.xml ├── doc2vec ├── dataset-links.txt ├── find_irrelevant_words.py ├── generate_json.py ├── load_doc2vec.py ├── output.json └── train_doc2vec.py ├── main.py ├── static ├── app.js ├── icon.png └── style.css └── templates └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | *.model* 92 | -------------------------------------------------------------------------------- /.idea/hackdelft.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 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 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 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 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | apple pay vs paypal 142 | activity 143 | avg 144 | get_objects_by_cluster 145 | gooda 146 | topic_words 147 | col-md-2 bar 148 | generate_view 149 | click 150 | topiclist 151 | background 152 | sort 153 | 154 | 155 | 156 | 158 | 159 | 170 | 171 | 172 | 173 | 174 | true 175 | DEFINITION_ORDER 176 | 177 | 178 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 204 | 205 | 208 | 209 | 210 | 211 | 214 | 215 | 218 | 219 | 222 | 223 | 224 | 225 | 228 | 229 | 232 | 233 | 236 | 237 | 240 | 241 | 242 | 243 | 246 | 247 | 250 | 251 | 254 | 255 | 258 | 259 | 260 | 261 | 264 | 265 | 268 | 269 | 272 | 273 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 312 | 313 | 330 | 331 | 348 | 349 | 366 | 367 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 409 | 410 | 423 | 424 | 441 | 442 | 454 | 455 | project 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 490 | 491 | 510 | 511 | 532 | 533 | 555 | 556 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 598 | 599 | 600 | 601 | 1494701848971 602 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 635 | 636 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | 730 | 731 | 732 | 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | 774 | 775 | 776 | 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # hackdelft 2 | HackDelft 3 | -------------------------------------------------------------------------------- /hackdelft/.gitignore: -------------------------------------------------------------------------------- 1 | #created by https://www.gitignore.io/api/python,pycharm 2 | 3 | ### PyCharm ### 4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 5 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 6 | 7 | # User-specific stuff: 8 | .idea/**/workspace.xml 9 | .idea/**/tasks.xml 10 | .idea/dictionaries 11 | 12 | # Sensitive or high-churn files: 13 | .idea/**/dataSources/ 14 | .idea/**/dataSources.ids 15 | .idea/**/dataSources.xml 16 | .idea/**/dataSources.local.xml 17 | .idea/**/sqlDataSources.xml 18 | .idea/**/dynamic.xml 19 | .idea/**/uiDesigner.xml 20 | 21 | # Gradle: 22 | .idea/**/gradle.xml 23 | .idea/**/libraries 24 | 25 | # CMake 26 | cmake-build-debug/ 27 | 28 | # Mongo Explorer plugin: 29 | .idea/**/mongoSettings.xml 30 | 31 | ## File-based project format: 32 | *.iws 33 | 34 | ## Plugin-specific files: 35 | 36 | # IntelliJ 37 | /out/ 38 | 39 | # mpeltonen/sbt-idea plugin 40 | .idea_modules/ 41 | 42 | # JIRA plugin 43 | atlassian-ide-plugin.xml 44 | 45 | # Cursive Clojure plugin 46 | .idea/replstate.xml 47 | 48 | # Crashlytics plugin (for Android Studio and IntelliJ) 49 | com_crashlytics_export_strings.xml 50 | crashlytics.properties 51 | crashlytics-build.properties 52 | fabric.properties 53 | 54 | ### PyCharm Patch ### 55 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 56 | 57 | # *.iml 58 | # modules.xml 59 | # .idea/misc.xml 60 | # *.ipr 61 | 62 | # Sonarlint plugin 63 | .idea/sonarlint 64 | 65 | ### Python ### 66 | # Byte-compiled / optimized / DLL files 67 | __pycache__/ 68 | *.py[cod] 69 | *$py.class 70 | 71 | # C extensions 72 | *.so 73 | 74 | # Distribution / packaging 75 | .Python 76 | env/ 77 | build/ 78 | develop-eggs/ 79 | dist/ 80 | downloads/ 81 | eggs/ 82 | .eggs/ 83 | lib/ 84 | lib64/ 85 | parts/ 86 | sdist/ 87 | var/ 88 | wheels/ 89 | *.egg-info/ 90 | .installed.cfg 91 | *.egg 92 | 93 | # PyInstaller 94 | # Usually these files are written by a python script from a template 95 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 96 | *.manifest 97 | *.spec 98 | 99 | # Installer logs 100 | pip-log.txt 101 | pip-delete-this-directory.txt 102 | 103 | # Unit test / coverage reports 104 | htmlcov/ 105 | .tox/ 106 | .coverage 107 | .coverage.* 108 | .cache 109 | nosetests.xml 110 | coverage.xml 111 | *,cover 112 | .hypothesis/ 113 | 114 | # Translations 115 | *.mo 116 | *.pot 117 | 118 | # Django stuff: 119 | *.log 120 | local_settings.py 121 | 122 | # Flask stuff: 123 | instance/ 124 | .webassets-cache 125 | 126 | # Scrapy stuff: 127 | .scrapy 128 | 129 | # Sphinx documentation 130 | docs/_build/ 131 | 132 | # PyBuilder 133 | target/ 134 | 135 | # Jupyter Notebook 136 | .ipynb_checkpoints 137 | 138 | # pyenv 139 | .python-version 140 | 141 | # celery beat schedule file 142 | celerybeat-schedule 143 | 144 | # SageMath parsed files 145 | *.sage.py 146 | 147 | # dotenv 148 | .env 149 | 150 | # virtualenv 151 | .venv 152 | venv/ 153 | ENV/ 154 | 155 | # Spyder project settings 156 | .spyderproject 157 | .spyproject 158 | 159 | # Rope project settings 160 | .ropeproject 161 | 162 | # mkdocs documentation 163 | /site 164 | 165 | # End of https://www.gitignore.io/api/python,pycharm 166 | -------------------------------------------------------------------------------- /hackdelft/.idea/hackdelft.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | -------------------------------------------------------------------------------- /hackdelft/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /hackdelft/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /hackdelft/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /hackdelft/doc2vec/find_irrelevant_words.py: -------------------------------------------------------------------------------- 1 | import re 2 | from collections import Counter 3 | 4 | 5 | def preprocess(str): 6 | # remove links 7 | str = re.sub(r'http(s)?:\/\/\S*? ', "", str) 8 | return str 9 | 10 | 11 | def preprocess_document(text): 12 | text = preprocess(text) 13 | return ''.join([x if x.isalnum() or x.isspace() else " " for x in text ]).split() 14 | 15 | f = open("cyber-trend-index-dataset-version2.txt") 16 | content = f.read() 17 | f.close() 18 | 19 | lines = content.lower().splitlines() 20 | 21 | prep = [preprocess_document(x) for x in lines] 22 | 23 | words = [x for sublist in prep for x in sublist] 24 | 25 | count = Counter(words) 26 | print(count.most_common()[:100]) -------------------------------------------------------------------------------- /hackdelft/doc2vec/generate_json.py: -------------------------------------------------------------------------------- 1 | import json 2 | import re 3 | 4 | import nltk 5 | from gensim.models import Doc2Vec 6 | from nltk.cluster import KMeansClusterer 7 | from nltk.corpus import stopwords 8 | 9 | NUM_CLUSTERS = 15 10 | 11 | def preprocess(str): 12 | # remove links 13 | str = re.sub(r'http(s)?:\/\/\S*? ', "", str) 14 | return str 15 | 16 | 17 | def preprocess_document(text): 18 | text = preprocess(text) 19 | return ''.join([x if x.isalnum() or x.isspace() else " " for x in text ]).split() 20 | 21 | 22 | 23 | with open('dataset-links.txt') as data_file: 24 | data = json.load(data_file) 25 | 26 | fname = "cyber-trend-index-dataset.model" 27 | model = Doc2Vec.load(fname) 28 | 29 | duplicate_abstracts = {} 30 | 31 | used_objects = [] 32 | vectors = [] 33 | for i, d in enumerate(data): 34 | abstract = d["abstract"].lower() 35 | if abstract not in duplicate_abstracts: 36 | duplicate_abstracts[abstract] = True 37 | used_objects.append(d) 38 | vectors.append(model.infer_vector(preprocess_document(abstract))) 39 | 40 | kclusterer = KMeansClusterer(NUM_CLUSTERS, distance=nltk.cluster.util.cosine_distance, repeats=25) 41 | assigned_clusters = kclusterer.cluster(vectors, assign_clusters=True) 42 | 43 | def get_objects_by_cluster(id): 44 | list = [] 45 | for x in range(0, len(assigned_clusters)): 46 | if (assigned_clusters[x] == id): 47 | list.append(used_objects[x]) 48 | return list 49 | 50 | def get_topics(objects): 51 | from collections import Counter 52 | words = [preprocess_document(x["abstract"].lower()) for x in objects] 53 | words = [word for sublist in words for word in sublist] 54 | filtered_words = [word for word in words if word not in stopwords.words('english') and not word.isdigit()] 55 | count = Counter(filtered_words) 56 | return count.most_common()[:5] 57 | 58 | json_data = [] 59 | for i in range(0,NUM_CLUSTERS): 60 | cur_obj = {} 61 | objects = get_objects_by_cluster(i) 62 | topics = get_topics(objects) 63 | avgactivity = 0 64 | goodactivity = 0 65 | goodcount = 0 66 | for x in range(0, len(objects)): 67 | avgactivity+=int(objects[x].get("activity"))/len(objects) 68 | goodactivity += int(objects[x].get("activity")) 69 | if (int(objects[x].get("activity")) > 0): goodcount+=1 70 | goodactivity=goodactivity/goodcount 71 | cur_obj["topics"] = topics 72 | cur_obj["avgactivity"] = avgactivity 73 | cur_obj["goodactivity"] = goodactivity 74 | cur_obj["articles"] = objects 75 | json_data.append(cur_obj) 76 | 77 | f = open("output.json", "w") 78 | json.dump(json_data, f) 79 | f.close() -------------------------------------------------------------------------------- /hackdelft/doc2vec/load_doc2vec.py: -------------------------------------------------------------------------------- 1 | import nltk, math, codecs 2 | from gensim.models import Doc2Vec 3 | from nltk.cluster.kmeans import KMeansClusterer 4 | import re 5 | 6 | from nltk.corpus import stopwords 7 | 8 | 9 | NUM_CLUSTERS = 20 10 | 11 | def preprocess(str): 12 | # remove links 13 | str = re.sub(r'http(s)?:\/\/\S*? ', "", str) 14 | return str 15 | 16 | 17 | def preprocess_document(text): 18 | text = preprocess(text) 19 | return ''.join([x if x.isalnum() or x.isspace() else " " for x in text ]).split() 20 | 21 | #data = .toarray() 22 | fname = "cyber-trend-index-dataset.model" 23 | model = Doc2Vec.load(fname) 24 | 25 | corpus = codecs.open('cyber-trend-index-dataset-small.txt', mode="r", encoding="utf-8") 26 | lines = corpus.read().lower().split("\n") 27 | count = len(lines) 28 | 29 | vectors = [] 30 | 31 | print("inferring vectors") 32 | duplicate_dict = {} 33 | used_lines = [] 34 | for i, t in enumerate(lines): 35 | if i % 2 == 0 and t not in duplicate_dict: 36 | duplicate_dict[t] = True 37 | used_lines.append(t) 38 | vectors.append(model.infer_vector(preprocess_document(t))) 39 | 40 | print("done") 41 | 42 | 43 | 44 | kclusterer = KMeansClusterer(NUM_CLUSTERS, distance=nltk.cluster.util.cosine_distance, repeats=25) 45 | assigned_clusters = kclusterer.cluster(vectors, assign_clusters=True) 46 | 47 | 48 | # clustersizes = [] 49 | # 50 | # def distanceToCentroid(): 51 | # for i in range(0,NUM_CLUSTERS): 52 | # clustersize = 0 53 | # for j in range(0,len(assigned_clusters)): 54 | # if (assigned_clusters[j] == i): 55 | # clustersize+=1 56 | # clustersizes.append(clustersize) 57 | # dist = 0.0 58 | # centr = means[i] 59 | # for j in range(0,len(assigned_clusters)): 60 | # if (assigned_clusters[j] == i): 61 | # dist += pow(nltk.cluster.util.cosine_distance(vectors[j], centr),2)/clustersize 62 | # dist = math.sqrt(dist) 63 | # print("distance cluster: "+str(i)+" RMSE: "+str(dist)+" clustersize: "+str(clustersize)) 64 | 65 | 66 | def get_titles_by_cluster(id): 67 | list = [] 68 | for x in range(0, len(assigned_clusters)): 69 | if (assigned_clusters[x] == id): 70 | list.append(used_lines[x]) 71 | return list 72 | 73 | def get_topics(titles): 74 | from collections import Counter 75 | words = [preprocess_document(x) for x in titles] 76 | words = [word for sublist in words for word in sublist] 77 | filtered_words = [word for word in words if word not in stopwords.words('english')] 78 | count = Counter(filtered_words) 79 | print(count.most_common()[:5]) 80 | 81 | 82 | def cluster_to_topics(id): 83 | get_topics(get_titles_by_cluster(id)) -------------------------------------------------------------------------------- /hackdelft/doc2vec/train_doc2vec.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import re 3 | from gensim.models.doc2vec import TaggedDocument, Doc2Vec 4 | 5 | logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO) 6 | 7 | def preprocess(str): 8 | # remove links 9 | str = re.sub(r'http(s)?:\/\/\S*? ', "", str) 10 | 11 | return str 12 | 13 | class Documents(object): 14 | def __init__(self, documents): 15 | self.documents = documents 16 | 17 | def __iter__(self): 18 | for i, doc in enumerate(self.documents): 19 | yield TaggedDocument(words = doc, tags = [i]) 20 | file = "cyber-trend-index-dataset-version2.txt" 21 | corpus = open(file, "r") 22 | lines = corpus.read().lower().split("\n") 23 | count = len(lines) 24 | preprocessed = [] 25 | 26 | duplicate_dict = {} 27 | 28 | for t in lines: 29 | if t not in duplicate_dict: 30 | duplicate_dict[t] = True 31 | t = preprocess(t) 32 | fixed =''.join([x if x.isalnum() or x.isspace() else " " for x in t ]).split() 33 | preprocessed.append(fixed) 34 | 35 | documents = Documents(preprocessed) 36 | 37 | 38 | 39 | 40 | #iter = 1, because we keep training ourselves :) 41 | model = Doc2Vec(size=100, dbow_words= 1, dm=0, iter=1, window=5, seed=1337, min_count=5, workers=4,alpha=0.025, min_alpha=0.025) 42 | model.build_vocab(documents) 43 | for epoch in range(10): 44 | print("epoch "+str(epoch)) 45 | model.train(documents, total_examples=count, epochs=1) 46 | model.save('cyber-trend-index-dataset.model') 47 | model.alpha -= 0.002 # decrease the learning rate 48 | model.min_alpha = model.alpha # fix the learning rate, no decay 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /hackdelft/main.py: -------------------------------------------------------------------------------- 1 | from flask import Flask, jsonify, render_template, url_for 2 | import json 3 | 4 | app = Flask(__name__) 5 | app.config.update(SERVER_NAME='127.0.0.1:5000') 6 | 7 | articles = {} 8 | 9 | with open("doc2vec/output.json") as json_file: 10 | articles['1'] = json.load(json_file) 11 | 12 | 13 | with app.app_context(): 14 | url_for('static', filename='style.css') 15 | 16 | @app.route('/') 17 | def index(): 18 | return render_template('index.html') 19 | 20 | @app.route('/api/articles/') 21 | def get_articles_by(term): 22 | return jsonify(articles[term]) 23 | 24 | 25 | @app.route('/api/articles/') 26 | def hello_world(): 27 | return jsonify(articles) -------------------------------------------------------------------------------- /hackdelft/static/app.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | loadTopics() 3 | }); 4 | 5 | function loadTopics() 6 | { 7 | $.ajax({ 8 | url: "api/articles/1", 9 | success: function (payload){processTopics(payload)}, 10 | }); 11 | } 12 | 13 | 14 | function processTopics(topics) { 15 | topics.sort(function (a, b) { 16 | if (a.goodactivity > b.goodactivity) { 17 | return -1; 18 | } 19 | if (a.goodactivity < b.goodactivity) { 20 | return 1; 21 | } 22 | // a must be equal to b 23 | return 0; 24 | }); 25 | topics.forEach(function(topic, index){ generate_view(topic, index)}) 26 | } 27 | 28 | function generate_view(topic, index) { 29 | console.log(topic); 30 | 31 | var topic_words = topic.topics.map(function (x) { 32 | return x[0] 33 | }); 34 | console.log("test"); 35 | $("#topiclist").append('
'+topic.goodactivity+'
'+topic_words.join(", ")+'
') 36 | 37 | $("#"+index).click(function () { 38 | loadUrls(topic.articles, topic_words) 39 | $(this).parent().children().removeClass("activate"); 40 | $(this).addClass("activate") 41 | }) 42 | } 43 | 44 | function loadUrls(articles, topics) { 45 | $("#articlelist").empty() 46 | articles.sort(function(a1, a2){ 47 | // console.log(topics) 48 | // console.log(a2.title.toLowerCase().split(" ")) 49 | 50 | return _.intersection(a2.title.toLowerCase().split(" "), topics).length - 51 | _.intersection(a1.title.toLowerCase().split(" "), topics).length 52 | }).forEach(function(article){ 53 | $("#articlelist").append(''); 54 | $("#articlelist").children().fadeIn(800) 55 | }) 56 | 57 | } -------------------------------------------------------------------------------- /hackdelft/static/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/olafmaas/hackdelft/43085896542654637c790c9dc2dd0772cbae6959/hackdelft/static/icon.png -------------------------------------------------------------------------------- /hackdelft/static/style.css: -------------------------------------------------------------------------------- 1 | .title { 2 | font-weight: bold; 3 | font-size: 20pt; 4 | font-family: 'Orbitron', sans-serif; 5 | margin-bottom: 0.25em; 6 | } 7 | 8 | .topic { 9 | height: 4em; 10 | padding-top: 0.75em; 11 | padding-bottom: 0.75em; 12 | font-weight: bold; 13 | color: white; 14 | font-size: 15pt; 15 | padding-left: auto; 16 | text-align: center; 17 | border-bottom: 1px solid white; 18 | font-family: 'Maven Pro', sans-serif; 19 | cursor: pointer; 20 | text-shadow: 0px 1px #000000; 21 | } 22 | 23 | .article{ 24 | 25 | text-shadow: 2px 2px #DDDDDD; 26 | } 27 | 28 | .topic:hover { 29 | opacity: 0.8; 30 | } 31 | 32 | .activate { 33 | text-decoration: underline; 34 | } 35 | 36 | .article { 37 | font-size: 15pt; 38 | padding-top: 0.5em; 39 | padding-bottom: 0.5em; 40 | } 41 | 42 | #articlelist { 43 | margin-left: 3em; 44 | } 45 | 46 | #logo { 47 | height: 2em; 48 | margin-right: 0.25em; 49 | } 50 | 51 | .right { 52 | float: left; 53 | width: 80%; 54 | } 55 | 56 | .left { 57 | float: left; 58 | width: 20%; 59 | } 60 | 61 | body { 62 | padding-top: 4em; 63 | 64 | } -------------------------------------------------------------------------------- /hackdelft/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | CybSec Summarizer 13 | 14 | 15 | 16 |
17 |
18 | Cyber Security Summarizer 19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
Please Select A Topic
27 |
28 |
29 |
30 | 31 | --------------------------------------------------------------------------------