├── .gitignore ├── LICENSE ├── Procfile ├── README.md ├── app.json ├── config ├── __init__.py ├── babel.cfg ├── development.py.template └── sample-data.json ├── databasic ├── __init__.py ├── celeryapp.py ├── forms.py ├── logic │ ├── __init__.py │ ├── connectthedots.py │ ├── db.py │ ├── filehandler.py │ ├── lazyfile.py │ ├── oauth.py │ ├── stopwords │ │ ├── __init__.py │ │ ├── danish │ │ ├── english │ │ ├── portuguese │ │ ├── spanish │ │ ├── welsh │ │ └── welsh_english │ ├── test │ │ ├── __init__.py │ │ ├── connectthedotsbigdatatest.py │ │ ├── connectthedotstest.py │ │ ├── dbtest.py │ │ ├── filehandlertest.py │ │ ├── fixtures │ │ │ ├── 22kAmazonGameReview.txt │ │ │ ├── HowAmericaInjuresItself_FromNEISS.xlsx │ │ │ ├── airline-routes-centralities.csv │ │ │ ├── airline-routes.csv │ │ │ ├── demo.docx │ │ │ ├── graph.gexf │ │ │ ├── handshake-problem.csv │ │ │ ├── invalid-graph.csv │ │ │ ├── latin-1.txt │ │ │ ├── les-miserables.csv │ │ │ ├── simple-network.csv │ │ │ ├── somerville-tree-details.csv │ │ │ ├── southern-women.csv │ │ │ ├── trailing-comma.csv │ │ │ ├── utf-8.txt │ │ │ └── zachary-karate-club.xlsx │ │ ├── wordhandlertest.py │ │ └── wtfcsvstattest.py │ ├── textanalysis.py │ ├── tfidfanalysis.py │ ├── wordhandler.py │ └── wtfcsvstat.py ├── mail.py ├── messages.pot ├── static │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── font-awesome.min.css │ ├── files │ │ ├── activity-guides │ │ │ ├── cy │ │ │ │ ├── Connect the Dots Activity Guide.pdf │ │ │ │ ├── SameDiff Activity Guide.pdf │ │ │ │ ├── WTFcsv Activity Guide.pdf │ │ │ │ └── WordCounter Activity Guide.pdf │ │ │ ├── da │ │ │ │ ├── Connect the Dots Activity Guide.pdf │ │ │ │ ├── SameDiff Activity Guide.pdf │ │ │ │ ├── WTFcsv Activity Guide.pdf │ │ │ │ └── WordCounter Activity Guide.pdf │ │ │ ├── en │ │ │ │ ├── Build a Data Sculpture.pdf │ │ │ │ ├── Connect the Dots Activity Guide.pdf │ │ │ │ ├── Data Diary.pdf │ │ │ │ ├── Embody a Dataset.pdf │ │ │ │ ├── Evaluating Your Story.pdf │ │ │ │ ├── Finding a story.pdf │ │ │ │ ├── Make a (Data) Scene.pdf │ │ │ │ ├── SameDiff Activity Guide.pdf │ │ │ │ ├── Sketch a Visual Word Web.pdf │ │ │ │ ├── WTFcsv Activity Guide.pdf │ │ │ │ └── WordCounter Activity Guide.pdf │ │ │ ├── en_CY │ │ │ │ ├── Connect the Dots Activity Guide.pdf │ │ │ │ ├── SameDiff Activity Guide.pdf │ │ │ │ ├── WTFcsv Activity Guide.pdf │ │ │ │ └── WordCounter Activity Guide.pdf │ │ │ ├── es │ │ │ │ ├── Connect the Dots Activity Guide.pdf │ │ │ │ ├── SameDiff Activity Guide.pdf │ │ │ │ ├── WTFcsv Activity Guide.pdf │ │ │ │ └── WordCounter Activity Guide.pdf │ │ │ └── pt │ │ │ │ ├── Connect the Dots Activity Guide.pdf │ │ │ │ ├── SameDiff Activity Guide.pdf │ │ │ │ ├── WTFcsv Activity Guide.pdf │ │ │ │ └── WordCounter Activity Guide.pdf │ │ ├── activity-materials │ │ │ ├── cy │ │ │ │ ├── Gweld_UFO_a Adroddwyd_Cymru.csv │ │ │ │ ├── Infographic Remix Cards.pdf │ │ │ │ ├── Picking a Technique.pdf │ │ │ │ ├── UFO_Sightings_Reported_Wales.csv │ │ │ │ └── Way_To_go_cym.png │ │ │ ├── da │ │ │ │ ├── Picking a Technique.pdf │ │ │ │ └── Vurder din fortælling - Evaluate Your Story.pdf │ │ │ ├── en │ │ │ │ ├── Infographic Remix Cards.pdf │ │ │ │ ├── Picking a Technique.pdf │ │ │ │ ├── Storytelling Techniques.pdf │ │ │ │ ├── data sculpture - MIT costs - rev3.pdf │ │ │ │ ├── data sculpture - happiness - rev2.pdf │ │ │ │ └── data sculpture - ice cream - rev2.pdf │ │ │ └── en_CY │ │ │ │ ├── Infographic Remix Cards.pdf │ │ │ │ ├── Picking a Technique.pdf │ │ │ │ ├── Storytelling Techniques.pdf │ │ │ │ ├── UFO_Sightings_Reported_Wales.csv │ │ │ │ ├── Way_To_go_ENG.png │ │ │ │ ├── data sculpture - MIT costs - rev3.pdf │ │ │ │ ├── data sculpture - happiness - rev2.pdf │ │ │ │ └── data sculpture - ice cream - rev2.pdf │ │ ├── examples │ │ │ └── storybook1.pdf │ │ └── user-templates │ │ │ ├── en │ │ │ └── ctd-template.csv │ │ │ ├── es │ │ │ └── ctd-template.csv │ │ │ └── pt │ │ │ └── ctd-template.csv │ ├── fonts │ │ ├── FontAwesome.otf │ │ ├── MyFontsWebfontsKit.js │ │ ├── avenir │ │ │ ├── AvenirNext-Bold.eot │ │ │ ├── AvenirNext-Bold.ttf │ │ │ ├── AvenirNext-Bold.woff │ │ │ ├── AvenirNext-Bold.woff2 │ │ │ ├── AvenirNext-Regular.eot │ │ │ ├── AvenirNext-Regular.ttf │ │ │ ├── AvenirNext-Regular.woff │ │ │ └── AvenirNext-Regular.woff2 │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ ├── fontawesome-webfont.woff2 │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ ├── glyphicons-halflings-regular.woff2 │ │ └── webfonts │ │ │ ├── 2F9E32_0_0.eot │ │ │ ├── 2F9E32_0_0.ttf │ │ │ ├── 2F9E32_0_0.woff │ │ │ ├── 2F9E32_0_0.woff2 │ │ │ ├── 2F9E32_0_unhinted_0.ttf │ │ │ ├── 2F9E32_0_unhinted_0.woff │ │ │ ├── 2F9E32_0_unhinted_0.woff2 │ │ │ ├── 2F9E32_1_0.eot │ │ │ ├── 2F9E32_1_0.ttf │ │ │ ├── 2F9E32_1_0.woff │ │ │ ├── 2F9E32_1_0.woff2 │ │ │ ├── 2F9E32_1_unhinted_0.ttf │ │ │ ├── 2F9E32_1_unhinted_0.woff │ │ │ ├── 2F9E32_1_unhinted_0.woff2 │ │ │ ├── 2F9E32_2_0.eot │ │ │ ├── 2F9E32_2_0.ttf │ │ │ ├── 2F9E32_2_0.woff │ │ │ ├── 2F9E32_2_0.woff2 │ │ │ ├── 2F9E32_2_unhinted_0.ttf │ │ │ ├── 2F9E32_2_unhinted_0.woff │ │ │ └── 2F9E32_2_unhinted_0.woff2 │ ├── gen │ │ ├── packed.css │ │ ├── packed.js │ │ └── packed_ctd.js │ ├── img │ │ ├── background_tile.png │ │ ├── background_tile_small.png │ │ ├── background_tile_tiny.png │ │ ├── backgrounds │ │ │ ├── tiled_background_blue.png │ │ │ ├── tiled_background_green.png │ │ │ ├── tiled_background_pink.png │ │ │ ├── tiled_background_red.png │ │ │ └── tiled_background_yellow.png │ │ ├── ctd-sheet-thumbnail.png │ │ ├── culture │ │ │ ├── analyzing-data-1.jpg │ │ │ ├── analyzing-data-1@2x.jpg │ │ │ ├── analyzing-data-1@3x.jpg │ │ │ ├── analyzing-data-2.jpg │ │ │ ├── analyzing-data-2@2x.jpg │ │ │ ├── analyzing-data-2@3x.jpg │ │ │ ├── arrow.png │ │ │ ├── asking-questions-1.jpg │ │ │ ├── asking-questions-1@2x.jpg │ │ │ ├── asking-questions-1@3x.jpg │ │ │ ├── asking-questions-2.jpg │ │ │ ├── asking-questions-2@2x.jpg │ │ │ ├── asking-questions-2@3x.jpg │ │ │ ├── coming-soon.png │ │ │ ├── convince-me-1.jpg │ │ │ ├── convince-me-1@2x.jpg │ │ │ ├── convince-me-1@3x.jpg │ │ │ ├── data-culture-project-logo.png │ │ │ ├── data-culture-project-logo@2x.png │ │ │ ├── data-culture-project-logo@3x.png │ │ │ ├── data-process-cy.png │ │ │ ├── data-process.png │ │ │ ├── databasic-logo-white-transparent-bg.png │ │ │ ├── databasic-logo-white-transparent-bg@2x.png │ │ │ ├── databasic-logo-white-transparent-bg@3x.png │ │ │ ├── databasic-right-decoration.png │ │ │ ├── deconstruct-samples.png │ │ │ ├── gathering-data-1.jpg │ │ │ ├── gathering-data-1@2x.jpg │ │ │ ├── gathering-data-1@3x.jpg │ │ │ ├── img-1102.jpg │ │ │ ├── img-1102@2x.jpg │ │ │ ├── img-1102@3x.jpg │ │ │ ├── paper-spreadsheet-0.jpg │ │ │ ├── paper-spreadsheet-1.jpg │ │ │ ├── paper-spreadsheet-welsh.jpg │ │ │ ├── remix-1.png │ │ │ ├── remix-cards-thumbnail.png │ │ │ ├── remix-handout-thumbnail.png │ │ │ ├── remix-water-thumbnail.png │ │ │ ├── sculpture-brazil.jpg │ │ │ ├── sketch-1.jpg │ │ │ ├── sketch-1@2x.jpg │ │ │ ├── sketch-1@3x.jpg │ │ │ ├── telling-your-story-1.jpg │ │ │ ├── telling-your-story-1@2x.jpg │ │ │ ├── telling-your-story-1@3x.jpg │ │ │ ├── virtual-icon.png │ │ │ ├── word-web-drawing.png │ │ │ └── word-web-social-exclusion-pt.png │ │ ├── data_basic_logo_128.png │ │ ├── data_basic_logo_512.png │ │ ├── databasic-logo-square.png │ │ ├── icons │ │ │ ├── favicon-152.png │ │ │ └── favicon.ico │ │ ├── logos │ │ │ ├── MIT-logo-white.svg │ │ │ ├── connectthedots_white.png │ │ │ ├── ctd.png │ │ │ ├── ctd@2x.png │ │ │ ├── databasic.png │ │ │ ├── databasic_white.png │ │ │ ├── el-large.png │ │ │ ├── el.png │ │ │ ├── northeastern.png │ │ │ ├── samediff.png │ │ │ ├── samediff_white.png │ │ │ ├── sd.png │ │ │ ├── sd@2x.png │ │ │ ├── wc.png │ │ │ ├── wc@2x.png │ │ │ ├── wordcounter.png │ │ │ ├── wordcounter_white.png │ │ │ ├── wtf.png │ │ │ ├── wtf@2x.png │ │ │ ├── wtfcsv.png │ │ │ └── wtfcsv_white.png │ │ ├── photos │ │ │ ├── home1.png │ │ │ ├── home2.png │ │ │ ├── home3.png │ │ │ ├── home4.png │ │ │ ├── home5.png │ │ │ └── home6.png │ │ ├── samediff-sheet-thumbnail.jpg │ │ ├── wordcounter-sheet-thumbnail.jpg │ │ └── wtfcsv-sheet-thumbnail.jpg │ ├── js │ │ ├── connectthedots-validate.js │ │ ├── connectthedots.js │ │ ├── lib │ │ │ ├── Gettext.js │ │ │ ├── Gettext.min.js │ │ │ ├── additional-methods.min.js │ │ │ ├── bootstrap.js │ │ │ ├── bootstrap.min.js │ │ │ ├── d3.layout.cloud.js │ │ │ ├── d3.min.js │ │ │ ├── d3.tip.js │ │ │ ├── highcharts.js │ │ │ ├── highcharts.src.js │ │ │ ├── jquery.flip.min.js │ │ │ ├── jquery.floatThead-slim.min.js │ │ │ ├── jquery.js │ │ │ ├── jquery.validate.min.js │ │ │ ├── saveSvgAsPng.js │ │ │ └── underscore.min.js │ │ ├── samediff-validate.js │ │ ├── samediff.js │ │ ├── tool.js │ │ ├── wordcounter-validate.js │ │ └── wtfcsv-validate.js │ └── sass │ │ ├── _base.scss │ │ ├── _results.scss │ │ ├── _tool.scss │ │ ├── connectthedots-results.scss │ │ ├── connectthedots.scss │ │ ├── culture.scss │ │ ├── home.scss │ │ ├── layout │ │ ├── _footer.scss │ │ ├── _header.scss │ │ └── _nav.scss │ │ ├── modules │ │ ├── _input.scss │ │ └── _mixins.scss │ │ ├── samediff-results.scss │ │ ├── samediff.scss │ │ ├── settings │ │ ├── _colors.scss │ │ └── _fonts.scss │ │ ├── themes │ │ ├── blue-theme.scss │ │ ├── default-theme.scss │ │ ├── green-theme.scss │ │ ├── home-theme.scss │ │ ├── red-theme.scss │ │ └── yellow-theme.scss │ │ ├── wordcounter-results.scss │ │ ├── wordcounter.scss │ │ ├── wtfcsv-results.scss │ │ └── wtfcsv.scss ├── tasks.py ├── templates │ ├── _language_selector.html │ ├── base.html │ ├── connectthedots │ │ ├── connectthedots.html │ │ ├── no_results.html │ │ └── results.html │ ├── culture │ │ ├── connections.html │ │ ├── convince.html │ │ ├── culture.html │ │ ├── culture_activity_base.html │ │ ├── culture_base.html │ │ ├── deconstruct.html │ │ ├── paper_spreadsheet.html │ │ ├── questions.html │ │ ├── remix.html │ │ ├── sculpture.html │ │ ├── sketch.html │ │ ├── storybook.html │ │ ├── testimonials.html │ │ └── word_webs.html │ ├── footer.html │ ├── header_base.html │ ├── home │ │ └── index.html │ ├── home_header.html │ ├── macros.html │ ├── no_results.html │ ├── samediff │ │ ├── no_results.html │ │ ├── results.html │ │ └── samediff.html │ ├── scripts.html │ ├── tool_base.html │ ├── tool_header.html │ ├── wordcounter │ │ ├── no_results.html │ │ ├── results.html │ │ ├── run-activity.html │ │ └── wordcounter.html │ └── wtfcsv │ │ ├── no_results.html │ │ ├── results.html │ │ └── wtfcsv.html ├── translations │ ├── cy │ │ └── LC_MESSAGES │ │ │ ├── messages.json │ │ │ ├── messages.mo │ │ │ └── messages.po │ ├── da │ │ └── LC_MESSAGES │ │ │ ├── messages.json │ │ │ ├── messages.mo │ │ │ └── messages.po │ ├── en_CY │ │ └── LC_MESSAGES │ │ │ ├── messages.json │ │ │ ├── messages.mo │ │ │ └── messages.po │ ├── es │ │ └── LC_MESSAGES │ │ │ ├── messages.json │ │ │ ├── messages.mo │ │ │ └── messages.po │ └── pt │ │ └── LC_MESSAGES │ │ ├── messages.json │ │ ├── messages.mo │ │ └── messages.po └── views │ ├── __init__.py │ ├── connectthedots.py │ ├── culture.py │ ├── home.py │ ├── samediff.py │ ├── wordcounter.py │ └── wtfcsv.py ├── dbutils.py ├── install.sh ├── nginx.conf.sigil ├── nltk.txt ├── requirements.txt ├── run.py ├── runtime.txt ├── scripts ├── __init__.py └── init_samples.py ├── server.wsgi ├── setup.py ├── setup.txt ├── showlocales.py ├── start.sh ├── test.py ├── translations-add-language.sh ├── translations-compile.sh ├── translations-init-RUN-ONLY-ONCE.sh └── translations-update.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .Python 3 | *.sublime-* 4 | *.pyc 5 | .profile 6 | sample-data/ 7 | instance/ 8 | venv/ 9 | catherinevenvdev/ 10 | activate/ 11 | terminal.glue 12 | config/settings.py 13 | config/google-credentials.json 14 | config/settings.config 15 | *.scss.css 16 | *.scss.css.map 17 | dump.rdb 18 | logs/*.log 19 | .env 20 | .webassets-cache/ 21 | config/development.py 22 | certs/ 23 | logs/*.log.* 24 | 25 | HANDY_SNIPPETS 26 | 27 | databasic/static/gen/packed_tool.js 28 | .idea 29 | assets 30 | 31 | databasic/static/gen/packed.js 32 | HANDY SNIPPETS FOR CATHERINE TO REMEMBER THINGS 33 | databasic/translations/cy/LC_MESSAGES/OLDmessages.json 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 MIT Center for Civic Media 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn databasic:app --workers $WORKERS --timeout 120 --log-file=- -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DataBasic 2 | ========= 3 | 4 | DataBasic is a suite of web-based data literacy tools and accompanying hands-on activities for journalists, data 5 | journalism classrooms and community advocacy groups. 6 | 7 | The suite includes: 8 | 9 | * **WTFcsv**: A web application that takes as input a CSV file and returns a summary of the fields, their data type, their range, and basic descriptive statistics. This is a prettier version of R’s “summary” command and aids at the outset of the data analysis process. 10 | * **WordCounter**: A basic word counting tool that takes unstructured text as input and returns word frequency, bigrams (two-word phrases) and trigrams (three-word phrases) 11 | * **SameDiff**: A tool that compares two text files to show words in common, and words that make each unique. 12 | * **ConnectTheDots**: A network analysis tool that takes an edgelist and turns it into a graph/table of nodes. 13 | 14 | Installation 15 | ------------ 16 | 17 | DataBasic is a Python 3.x [Flask](https://flask.palletsprojects.com/) app. Make sure you have mongodb installed. 18 | 19 | **1.** Clone this repository and cd into it. 20 | ``` 21 | git clone https://github.com/rahulbot/DataBasic.git 22 | cd DataBasic 23 | ``` 24 | 25 | **2.** Copy `config/development.py.template` to `config/development.py` and enter your settings. 26 | 27 | **3.** Create a venv and install the requirements: 28 | ``` 29 | pip install -r requirements.txt 30 | ``` 31 | 32 | **4.** 33 | To develop on OSX, like we do, you might need to do this: 34 | ``` 35 | STATIC_DEPS=true pip install lxml 36 | ``` 37 | 38 | **5.** Start the app. Run this and then go to http://localhost:8000 in your browser: 39 | ``` 40 | gunicorn databasic:app 41 | ``` 42 | 43 | Deploying 44 | --------- 45 | 46 | This is built to deploy in a container (we use Dokku). Set the `WORKERS` environment variable to set how many 47 | workers gunicorn starts with. 48 | 49 | ### Heroku 50 | 51 | For deploying to Heroku, install and use the [scipy buildpack](https://github.com/thenovices/heroku-buildpack-scipy). 52 | 53 | On your dyno make sure you set up an environment variable for each property in the `config/development.py` file. 54 | 55 | ### Ubuntu 56 | 57 | You'll need to do some extra stuff on Ubuntu to get all the libraries working: 58 | 59 | ``` 60 | sudo apt-get install libblas-dev liblapack-dev libatlas-base-dev libamd2.2.0 libblas3gf libc6 libgcc1 libgfortran3 liblapack3gf libumfpack5.4.0 libstdc++6 build-essential gfortran python-all-dev libatlas-base-dev 61 | ``` 62 | 63 | Also you probably want to do `apt-get install python-numpy` and modify your virtualenv with 64 | `virtualenv VIRTUALENV_DIR --system-site-packages`. 65 | 66 | If after running you get an exception involving sassutils/SassMiddleware, 67 | [make sure your C++ compiler is up to date](https://github.com/sass/libsass#readme) 68 | 69 | You probably will need to compile the sass by hand: `python setup.py build_sass` 70 | 71 | Upgrading 72 | --------- 73 | 74 | If we've changed the document structures at all, when updating you'll want to remove all the 75 | sample data so it gets regenerated: 76 | 77 | ``` 78 | python dbutils.py -rm-samples 79 | ``` 80 | 81 | Translating 82 | ----------- 83 | 84 | We have built DataBasic to support multiple languages in the user interface. 85 | 86 | ### Setup 87 | ``` 88 | $ bash translations-init-RUN-ONLY-ONCE.sh 89 | ``` 90 | This initializes the translation files. You should only do this once or it'll erase your existing .po files that have 91 | translations. 92 | 93 | ### Add Language 94 | ``` 95 | $ bash translations-add-language.sh [LANGUAGE ARGUMENT] 96 | ``` 97 | Run the above bash command for each language you want the app to support (such as "es", "de", "hu"). This will create 98 | a translations directory and a PO file for that language. 99 | 100 | ### Updating 101 | ``` 102 | $ bash translations-update.sh 103 | ``` 104 | This command extracts all items for translation from the app. Each time you add a new bit of text you need to run this 105 | command. Then translate the .po file. If any translations in the .po are marked fuzzy, check them to for accuracy and 106 | then remove 'fuzzy.' 107 | ``` 108 | $ bash translations-compile.sh [LANGUAGE ARGUMENT] 109 | ``` 110 | This command compiles the translations from the .po files into binary form. You need to run this every time you 111 | update a .po file. Then restart the app. 112 | 113 | Seeking Databasic Translators 114 | ----------------------------- 115 | 116 | Want to see Databasic in another language? We would love your help in making that happen. Languages of interest 117 | include French and Arabic. 118 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DataBasic", 3 | "description": "Build your Data Culture", 4 | "scripts": { 5 | "dokku": { 6 | "predeploy": "./install.sh" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/config/__init__.py -------------------------------------------------------------------------------- /config/babel.cfg: -------------------------------------------------------------------------------- 1 | [python: **.py] 2 | [javascript: **.js] 3 | [jinja2: **/templates/**.html] 4 | extensions=jinja2.ext.autoescape,jinja2.ext.with_,webassets.ext.jinja2.AssetsExtension 5 | encoding=utf-8 6 | silent=false 7 | extract_messages = $._, jQuery._ -------------------------------------------------------------------------------- /config/development.py.template: -------------------------------------------------------------------------------- 1 | 2 | # Put a unique hexadecimal token in here (needed by our forms library). 3 | SECRET_KEY = 'SECRET_KEY' 4 | 5 | # Put in the url for your mongodb server, and the database name on that server. 6 | MONGODB_URL = 'mongodb://localhost/' 7 | MONGODB_NAME = 'databasic-dev' 8 | 9 | # To allow processing of google spreadsheets in WTFcsv, you need to put in a Google API token here. 10 | # Create a project in the Google Developers Console and copy the credentials here. 11 | # https://console.developers.google.com/project/_/apiui/credential 12 | GOOGLE_CLIENT_ID = "MY_CLIENT_ID" 13 | GOOGLE_CLIENT_SECRET = "MY_SECRET_ID" 14 | 15 | # To track visits put in a google analytics id here. 16 | GOOGLE_ANALYTICS_ID = '' 17 | 18 | # If you are deploying in production to a read-only filesystem you'll need to put a that url in here. 19 | SAMPLE_DATA_SERVER = 'http://my.static.server.for.stuff/' 20 | 21 | # Set to boolean True or False for Flask debugging assists. 22 | DEBUG = True 23 | 24 | # Set this to the url Google should redirect to after OAuth has been set up 25 | OAUTH_REDIRECT_URI = "http://127.0.0.1:8000/auth" 26 | 27 | # set to byte limit for file uploads. 10,485,760 is recommended for 10MB 28 | MAX_CONTENT_LENGTH = 10485760 29 | 30 | # Cache sample data analysis. Turn off for debugging or updating data sets. 31 | CACHE_SAMPLE_DATA_ANALYSIS = False -------------------------------------------------------------------------------- /databasic/celeryapp.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | from celery import Celery 4 | from databasic import settings 5 | 6 | celery_app = Celery('databasic', 7 | broker=settings.get('queue','broker_url'), 8 | backend=settings.get('queue','backend_url'), 9 | include=['databasic.tasks']) 10 | 11 | # expire backend results in one hour 12 | celery_app.conf.update( 13 | CELERY_TASK_RESULT_EXPIRES=3600 14 | ) 15 | 16 | if __name__ == '__main__': 17 | celery_app.start() -------------------------------------------------------------------------------- /databasic/logic/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/logic/__init__.py -------------------------------------------------------------------------------- /databasic/logic/db.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import logging 3 | import time 4 | import pytz 5 | from pymongo import MongoClient 6 | from bson.objectid import ObjectId 7 | 8 | EXPIRE_AFTER = 60 # time in days 9 | logger = logging.getLogger(__name__) 10 | 11 | 12 | class MongoHandler: 13 | 14 | def __init__(self, uri, db_name): 15 | logger.info("Connected to '{}' Mongo collection at {}".format(db_name, uri)) 16 | self._client = MongoClient(uri, connect=False) 17 | self._db = self._client[db_name] 18 | 19 | def save_words(self, collection, counts, ignore_case, ignore_stopwords, title, sample_id, source, extras=None): 20 | data_to_save = extras if extras is not None else {} 21 | data_to_save.update({ 22 | 'counts': counts, 23 | 'ignore_case': ignore_case, 24 | 'ignore_stopwords': ignore_stopwords, 25 | 'title': title, 26 | 'sample_id': str(sample_id), 27 | 'source': source, 28 | 'created_at': time.time(), 29 | }) 30 | result = self._db[collection].insert_one(data_to_save) 31 | return str(result.inserted_id) 32 | 33 | def results_for_sample(self, collection, sample_id): 34 | logger.debug("checking for sample %s", sample_id) 35 | sample = self._db[collection].find_one({'sample_id': str(sample_id)}) 36 | 37 | if sample is not None: 38 | return str(sample['_id']) 39 | 40 | def save_csv(self, collection, results, sample_id, source): 41 | result = self._db[collection].insert_one({ 42 | 'results': results, 43 | 'sample_id': str(sample_id), 44 | 'source': source, 45 | 'created_at': time.time() 46 | }) 47 | return str(result.inserted_id) 48 | 49 | def save_samediff(self, collection, filenames, total_words_doc1, total_words_doc2, diff_words_doc1, diff_words_doc2, 50 | same_words, same_word_counts, most_frequent_doc1, most_frequent_doc2, cosine_similarity, titles, 51 | sample_id, source): 52 | result = self._db[collection].insert_one({ 53 | 'filenames': filenames, 54 | 'totalWordsDoc1': total_words_doc1, 55 | 'totalWordsDoc2': total_words_doc2, 56 | 'diffWordsDoc1': diff_words_doc1, 57 | 'diffWordsDoc2': diff_words_doc2, 58 | 'sameWords': same_words, 59 | 'sameWordCounts': same_word_counts, 60 | 'mostFrequentDoc1': most_frequent_doc1, 61 | 'mostFrequentDoc2': most_frequent_doc2, 62 | 'cosineSimilarity': cosine_similarity, 63 | 'titles': titles, 64 | 'sample_id': str(sample_id), 65 | 'source': source, 66 | 'created_at': time.time() 67 | }) 68 | return str(result.inserted_id) 69 | 70 | 71 | def save_job(self, collection, job_info): 72 | self._db[collection].insert_one(job_info) 73 | 74 | def find_document(self, collection, doc_id): 75 | logger.debug("trying to find one doc with ID %s", doc_id) 76 | return self._db[collection].find_one({'_id': ObjectId(doc_id)}) 77 | 78 | def get_remaining_days(self, collection, doc_id): 79 | doc = self.find_document(collection, doc_id)['_id'] 80 | now = datetime.datetime.now(pytz.utc) 81 | age = now-doc.generation_time 82 | remaining = datetime.timedelta(days=EXPIRE_AFTER)-age 83 | return remaining.days+1 84 | 85 | def remove_all_sample_data(self): 86 | self.remove_sample_data('wordcounter') 87 | self.remove_sample_data('wtfcsv') 88 | self.remove_sample_data('samediff') 89 | self.remove_sample_data('connectthedots') 90 | logger.debug("Removed all sample data") 91 | 92 | def remove_sample_data(self, collection): 93 | self._db[collection].delete_many({'sample_id': {'$exists': True, '$ne': ''}}) 94 | 95 | def remove_expired_results(self, collection): 96 | limit = datetime.datetime.now(pytz.utc) - datetime.timedelta(days=EXPIRE_AFTER) 97 | _id = ObjectId.from_datetime(limit) 98 | docs = self._db[collection].find({'_id': {'$lt': _id}, 'sample_id': ''}) 99 | for d in docs: 100 | if 'title' in d: 101 | logger.info(collection + ': removing ' + d['title']) 102 | else: 103 | logger.info(collection + ': removing (no name)') 104 | self._db[collection].delete_many({'_id': {'$lt': _id}, 'sample_id': ''}) 105 | 106 | def remove_all_expired_results(self): 107 | self.remove_expired_results('wordcounter') 108 | self.remove_expired_results('wtfcsv') 109 | self.remove_expired_results('samediff') 110 | self.remove_expired_results('connectthedots') 111 | 112 | def remove_by_id(self, collection, id): 113 | return self._db[collection].delete_one({'_id': ObjectId(id)}) 114 | -------------------------------------------------------------------------------- /databasic/logic/lazyfile.py: -------------------------------------------------------------------------------- 1 | import six 2 | 3 | class LazyFile(six.Iterator): 4 | """ 5 | A proxy for a File object that delays opening it until 6 | a read method is called. 7 | Currently this implements only the minimum methods to be useful, 8 | but it could easily be expanded. 9 | """ 10 | def __init__(self, init, *args, **kwargs): 11 | self.init = init 12 | self.f = None 13 | self._is_lazy_opened = False 14 | 15 | self._lazy_args = args 16 | self._lazy_kwargs = kwargs 17 | 18 | def __getattr__(self, name): 19 | if not self._is_lazy_opened: 20 | self.f = self.init(*self._lazy_args, **self._lazy_kwargs) 21 | self._is_lazy_opened = True 22 | 23 | return getattr(self.f, name) 24 | 25 | def __iter__(self): 26 | return self 27 | 28 | def close(self): 29 | self.f.close() 30 | self.f = None 31 | self._is_lazy_opened = False 32 | 33 | def __next__(self): 34 | if not self._is_lazy_opened: 35 | self.f = self.init(*self._lazy_args, **self._lazy_kwargs) 36 | self._is_lazy_opened = True 37 | 38 | return next(self.f) -------------------------------------------------------------------------------- /databasic/logic/oauth.py: -------------------------------------------------------------------------------- 1 | import os, sys, json, gspread, logging 2 | import gdata.docs.service 3 | from oauth2client.client import SignedJwtAssertionCredentials, OAuth2WebServerFlow 4 | 5 | _oauth = None # singleton instance 6 | 7 | logger = logging.getLogger(__name__) 8 | 9 | ''' 10 | Public API 11 | ''' 12 | def init(client_id,client_secret,redirect_uri): 13 | global _oauth 14 | logger.info("Init oauth with redirect to %s", redirect_uri) 15 | if len(client_id)>0 and len(client_secret)>0: 16 | logging.info("Initialized oauth with id & secret") 17 | _oauth = OAuthHandler(client_id,client_secret,redirect_uri) 18 | else: 19 | logging.error("No client_id and client_secret specificed - oauth won't work!") 20 | 21 | def authorize(code): 22 | logger.debug("authorize %s", code) 23 | _oauth.authorize(code) 24 | 25 | def open_doc_from_url(url, redirect_to): 26 | logger.debug("open_doc %s -> %s", url, redirect_to) 27 | _oauth.redirect_to = redirect_to 28 | if not _oauth.authorized: 29 | logger.warning("not authorized %s -> %s", url, redirect_to) 30 | _oauth.doc_url = url 31 | return { 32 | 'authenticate': _oauth.authenticate_app(), 33 | 'doc': None 34 | } 35 | else: 36 | logger.debug("authorized for %s -> %s", url, redirect_to) 37 | _oauth.doc_url = None 38 | return { 39 | 'authenticate': None, 40 | 'doc': _oauth.open_url(url) 41 | } 42 | 43 | def redirect_to(): 44 | return _oauth.redirect_to 45 | 46 | def doc_url(): 47 | return _oauth.get_doc_url() 48 | 49 | ''' 50 | Handler for Google's OAuth2 51 | https://gist.github.com/cspickert/1650271 52 | ''' 53 | class OAuthHandler: 54 | 55 | def __init__(self, client_id, client_secret, redirect_uri): 56 | self.authorized = False 57 | self.redirect_to = '' # the url to return to after the user has granted permissions 58 | self.doc_url = None # the url of the doc to open after the user has granted permissions 59 | self._data_client = gdata.docs.service.DocsService() # used for docs 60 | self._key = { 'client_id': client_id, 'client_secret': client_secret} 61 | self._client = None # initialize so we can check later 62 | self.flow = OAuth2WebServerFlow( 63 | client_id=self._key['client_id'], 64 | client_secret=self._key['client_secret'], 65 | scope=[ 66 | 'https://www.googleapis.com/auth/drive.readonly', 67 | 'https://spreadsheets.google.com/feeds', 68 | 'https://docs.google.com/feeds'], 69 | redirect_uri=redirect_uri) 70 | 71 | def authenticate_app(self): 72 | logger.debug("OAuthHandler.authenticate_app") 73 | return self.flow.step1_get_authorize_url() 74 | 75 | def authorize(self, code): 76 | logger.debug("OAuthHandler.authorize") 77 | credentials = self.flow.step2_exchange(code) 78 | self._client = gspread.authorize(credentials) 79 | self._data_client.ClientLogin(self._key['client_id'], self._key['client_secret']) 80 | self.authorized = True 81 | 82 | def open_url(self, url): 83 | # TODO: make this work with docs as well (only spreadsheets work at the moment) 84 | # ^^ (this is very hard :o) ^^ 85 | if self._client is None: 86 | logger.debug("OAuthHandler doesn't have _client yet") 87 | return None 88 | try: 89 | logger.debug("OAuthHandler.open_url") 90 | return self._client.open_by_url(url) 91 | except gspread.SpreadsheetNotFound: 92 | logger.error("open_url: spreadsheet not found %s", url) 93 | self.authorized = False 94 | return None 95 | except gspread.NoValidUrlKeyFound: 96 | logger.error("open_url: no valid url found %s", url) 97 | self.authorized = False 98 | return None 99 | 100 | def get_doc_url(self): 101 | logger.debug("get_doc_url") 102 | if self.doc_url is None: 103 | return None 104 | u = self.open_url(self.doc_url) 105 | self.doc_url = None 106 | return u 107 | -------------------------------------------------------------------------------- /databasic/logic/stopwords/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from nltk.corpus import stopwords 3 | import logging 4 | 5 | from databasic import get_base_dir 6 | 7 | logger = logging.getLogger(__name__) 8 | 9 | language2stopwords = {} # cache of language name to our custom stopwords list 10 | 11 | 12 | def remove_from_freq_dist(fdist, language): 13 | # http://stackoverflow.com/questions/7154312/how-do-i-remove-entries-within-a-counter-object-with-a-loop-without-invoking-a-r 14 | num_removed = 0 15 | custom_stopwords = _custom_stopwords_list(language) 16 | # logger.debug(",".join(custom_stopwords)) 17 | 18 | #Check if nltk supports this language 19 | standard_stopwords = [] 20 | try: 21 | standard_stopwords = stopwords.words(language) 22 | except IOError: 23 | logger.debug("Couldn't find stopwords for {}. Probbaly because nltk doesn't support it.".format(language)) 24 | 25 | 26 | for w in list(fdist): 27 | if (w in standard_stopwords) or (w in custom_stopwords): 28 | num_removed += 1 29 | del fdist[w] 30 | 31 | logger.debug(" removed {} stopwords".format(num_removed)) 32 | return fdist 33 | 34 | 35 | def _custom_stopwords_list(language, force=True): 36 | """ 37 | We have some extra stopwords that we want to use in some of our languages 38 | :param language: NLTK-compatible name of language 39 | :return: a list of stopwords we added for that language, [] if none to add 40 | """ 41 | 42 | if force or (language not in language2stopwords): 43 | path_to_file = os.path.join(get_base_dir(), 'databasic', 'logic', 'stopwords', language) 44 | try: 45 | f = open(path_to_file, 'r') 46 | custom_stopwords = [w.strip() for w in f.readlines() if len(w.strip()) > 0] 47 | logger.debug("Loaded {} custom {} stopwords".format(len(custom_stopwords), language)) 48 | f.close() 49 | except OSError: 50 | custom_stopwords = [] 51 | language2stopwords[language] = custom_stopwords 52 | # speed things up by caching the stopword lists in memory, so it isn't file I/O bound 53 | return language2stopwords[language] 54 | -------------------------------------------------------------------------------- /databasic/logic/stopwords/danish: -------------------------------------------------------------------------------- 1 | og 2 | i 3 | jeg 4 | det 5 | at 6 | en 7 | den 8 | til 9 | er 10 | som 11 | på 12 | de 13 | med 14 | han 15 | af 16 | for 17 | ikke 18 | der 19 | var 20 | mig 21 | sig 22 | men 23 | et 24 | har 25 | om 26 | vi 27 | min 28 | havde 29 | ham 30 | hun 31 | nu 32 | over 33 | da 34 | fra 35 | du 36 | ud 37 | sin 38 | dem 39 | os 40 | op 41 | man 42 | hans 43 | hvor 44 | eller 45 | hvad 46 | skal 47 | selv 48 | her 49 | alle 50 | vil 51 | blev 52 | kunne 53 | ind 54 | når 55 | være 56 | dog 57 | noget 58 | ville 59 | jo 60 | deres 61 | efter 62 | ned 63 | skulle 64 | denne 65 | end 66 | dette 67 | mit 68 | også 69 | under 70 | have 71 | dig 72 | anden 73 | hende 74 | mine 75 | alt 76 | meget 77 | sit 78 | sine 79 | vor 80 | mod 81 | disse 82 | hvis 83 | din 84 | nogle 85 | hos 86 | blive 87 | mange 88 | ad 89 | bliver 90 | hendes 91 | været 92 | thi 93 | jer 94 | sådan 95 | derpaa 96 | faa 97 | faar 98 | herpaa 99 | hvornaar 100 | maa 101 | maaske 102 | naar 103 | ogsaa 104 | paa 105 | saa 106 | saadan 107 | saaledes 108 | -------------------------------------------------------------------------------- /databasic/logic/stopwords/english: -------------------------------------------------------------------------------- 1 | i 2 | me 3 | my 4 | myself 5 | we 6 | our 7 | ours 8 | ourselves 9 | you 10 | your 11 | yours 12 | yourself 13 | yourselves 14 | he 15 | him 16 | his 17 | himself 18 | she 19 | her 20 | hers 21 | herself 22 | it 23 | its 24 | itself 25 | they 26 | them 27 | their 28 | theirs 29 | themselves 30 | what 31 | which 32 | who 33 | whom 34 | this 35 | that 36 | these 37 | those 38 | am 39 | is 40 | are 41 | was 42 | were 43 | be 44 | been 45 | being 46 | have 47 | has 48 | had 49 | having 50 | do 51 | does 52 | did 53 | doing 54 | a 55 | an 56 | the 57 | and 58 | but 59 | if 60 | or 61 | because 62 | as 63 | until 64 | while 65 | of 66 | at 67 | by 68 | for 69 | with 70 | about 71 | against 72 | between 73 | into 74 | through 75 | during 76 | before 77 | after 78 | above 79 | below 80 | to 81 | from 82 | up 83 | down 84 | in 85 | out 86 | on 87 | off 88 | over 89 | under 90 | again 91 | further 92 | then 93 | once 94 | here 95 | there 96 | when 97 | where 98 | why 99 | how 100 | all 101 | any 102 | both 103 | each 104 | few 105 | more 106 | most 107 | other 108 | some 109 | such 110 | no 111 | nor 112 | not 113 | only 114 | own 115 | same 116 | so 117 | than 118 | too 119 | very 120 | s 121 | t 122 | can 123 | will 124 | just 125 | don 126 | should 127 | now 128 | -------------------------------------------------------------------------------- /databasic/logic/stopwords/portuguese: -------------------------------------------------------------------------------- 1 | a 2 | à 3 | ainda 4 | ano 5 | anos 6 | ao 7 | aos 8 | apenas 9 | as 10 | às 11 | até 12 | brasil 13 | com 14 | como 15 | contra 16 | da 17 | das 18 | de 19 | depois 20 | deve 21 | dia 22 | disse 23 | diz 24 | do 25 | dois 26 | dos 27 | e 28 | é 29 | ela 30 | ele 31 | em 32 | entre 33 | era 34 | está 35 | estado 36 | estão 37 | eu 38 | foi 39 | folha 40 | foram 41 | governo 42 | grande 43 | há 44 | hoje 45 | isso 46 | já 47 | local 48 | maior 49 | mais 50 | mas 51 | mercado 52 | mesmo 53 | mil 54 | milhões 55 | muito 56 | mundo 57 | na 58 | não 59 | nas 60 | no 61 | nos 62 | o 63 | ontem 64 | os 65 | ou 66 | país 67 | para 68 | paulo 69 | pela 70 | pelo 71 | pessoas 72 | pode 73 | por 74 | porque 75 | presidente 76 | quando 77 | que 78 | quem 79 | r 80 | rio 81 | são 82 | se 83 | segundo 84 | sem 85 | ser 86 | será 87 | seu 88 | seus 89 | só 90 | sobre 91 | sua 92 | também 93 | tem 94 | ter 95 | todos 96 | três 97 | um 98 | uma 99 | us 100 | vai 101 | de 102 | a 103 | o 104 | que 105 | e 106 | do 107 | da 108 | em 109 | um 110 | para 111 | com 112 | não 113 | uma 114 | os 115 | no 116 | se 117 | na 118 | por 119 | mais 120 | as 121 | dos 122 | como 123 | mas 124 | ao 125 | ele 126 | das 127 | à 128 | seu 129 | sua 130 | ou 131 | quando 132 | muito 133 | nos 134 | já 135 | eu 136 | também 137 | só 138 | pelo 139 | pela 140 | até 141 | isso 142 | ela 143 | entre 144 | depois 145 | sem 146 | mesmo 147 | aos 148 | seus 149 | quem 150 | nas 151 | me 152 | esse 153 | eles 154 | você 155 | essa 156 | num 157 | nem 158 | suas 159 | meu 160 | às 161 | minha 162 | numa 163 | pelos 164 | elas 165 | qual 166 | nós 167 | lhe 168 | deles 169 | essas 170 | esses 171 | pelas 172 | este 173 | dele 174 | tu 175 | te 176 | vocês 177 | vos 178 | lhes 179 | meus 180 | minhas 181 | teu 182 | tua 183 | teus 184 | tuas 185 | nosso 186 | nossa 187 | nossos 188 | nossas 189 | dela 190 | delas 191 | esta 192 | estes 193 | estas 194 | aquele 195 | aquela 196 | aqueles 197 | aquelas 198 | isto 199 | aquilo 200 | estou 201 | está 202 | estamos 203 | estão 204 | estive 205 | esteve 206 | estivemos 207 | estiveram 208 | estava 209 | estávamos 210 | estavam 211 | estivera 212 | estivéramos 213 | esteja 214 | estejamos 215 | estejam 216 | estivesse 217 | estivéssemos 218 | estivessem 219 | estiver 220 | estivermos 221 | estiverem 222 | hei 223 | há 224 | havemos 225 | hão 226 | houve 227 | houvemos 228 | houveram 229 | houvera 230 | houvéramos 231 | haja 232 | hajamos 233 | hajam 234 | houvesse 235 | houvéssemos 236 | houvessem 237 | houver 238 | houvermos 239 | houverem 240 | houverei 241 | houverá 242 | houveremos 243 | houverão 244 | houveria 245 | houveríamos 246 | houveriam 247 | sou 248 | somos 249 | são 250 | era 251 | éramos 252 | eram 253 | fui 254 | foi 255 | fomos 256 | foram 257 | fora 258 | fôramos 259 | seja 260 | sejamos 261 | sejam 262 | fosse 263 | fôssemos 264 | fossem 265 | for 266 | formos 267 | forem 268 | serei 269 | será 270 | seremos 271 | serão 272 | seria 273 | seríamos 274 | seriam 275 | tenho 276 | tem 277 | temos 278 | tém 279 | tinha 280 | tínhamos 281 | tinham 282 | tive 283 | teve 284 | tivemos 285 | tiveram 286 | tivera 287 | tivéramos 288 | tenha 289 | tenhamos 290 | tenham 291 | tivesse 292 | tivéssemos 293 | tivessem 294 | tiver 295 | tivermos 296 | tiverem 297 | terei 298 | terá 299 | teremos 300 | terão 301 | teria 302 | teríamos 303 | teriam 304 | -------------------------------------------------------------------------------- /databasic/logic/stopwords/spanish: -------------------------------------------------------------------------------- 1 | de 2 | la 3 | que 4 | el 5 | en 6 | y 7 | a 8 | los 9 | del 10 | se 11 | las 12 | por 13 | un 14 | para 15 | con 16 | no 17 | una 18 | su 19 | al 20 | lo 21 | como 22 | más 23 | pero 24 | sus 25 | le 26 | ya 27 | o 28 | este 29 | sí 30 | porque 31 | esta 32 | entre 33 | cuando 34 | muy 35 | sin 36 | sobre 37 | también 38 | me 39 | hasta 40 | hay 41 | donde 42 | quien 43 | desde 44 | todo 45 | nos 46 | durante 47 | todos 48 | uno 49 | les 50 | ni 51 | contra 52 | otros 53 | ese 54 | eso 55 | ante 56 | ellos 57 | e 58 | esto 59 | mí 60 | antes 61 | algunos 62 | qué 63 | unos 64 | yo 65 | otro 66 | otras 67 | otra 68 | él 69 | tanto 70 | esa 71 | estos 72 | mucho 73 | quienes 74 | nada 75 | muchos 76 | cual 77 | poco 78 | ella 79 | estar 80 | estas 81 | algunas 82 | algo 83 | nosotros 84 | mi 85 | mis 86 | tú 87 | te 88 | ti 89 | tu 90 | tus 91 | ellas 92 | nosotras 93 | vosostros 94 | vosostras 95 | os 96 | mío 97 | mía 98 | míos 99 | mías 100 | tuyo 101 | tuya 102 | tuyos 103 | tuyas 104 | suyo 105 | suya 106 | suyos 107 | suyas 108 | nuestro 109 | nuestra 110 | nuestros 111 | nuestras 112 | vuestro 113 | vuestra 114 | vuestros 115 | vuestras 116 | esos 117 | esas 118 | estoy 119 | estás 120 | está 121 | estamos 122 | estáis 123 | están 124 | esté 125 | estés 126 | estemos 127 | estéis 128 | estén 129 | estaré 130 | estarás 131 | estará 132 | estaremos 133 | estaréis 134 | estarán 135 | estaría 136 | estarías 137 | estaríamos 138 | estaríais 139 | estarían 140 | estaba 141 | estabas 142 | estábamos 143 | estabais 144 | estaban 145 | estuve 146 | estuviste 147 | estuvo 148 | estuvimos 149 | estuvisteis 150 | estuvieron 151 | estuviera 152 | estuvieras 153 | estuviéramos 154 | estuvierais 155 | estuvieran 156 | estuviese 157 | estuvieses 158 | estuviésemos 159 | estuvieseis 160 | estuviesen 161 | estando 162 | estado 163 | estada 164 | estados 165 | estadas 166 | estad 167 | he 168 | has 169 | ha 170 | hemos 171 | habéis 172 | han 173 | haya 174 | hayas 175 | hayamos 176 | hayáis 177 | hayan 178 | habré 179 | habrás 180 | habrá 181 | habremos 182 | habréis 183 | habrán 184 | habría 185 | habrías 186 | habríamos 187 | habríais 188 | habrían 189 | había 190 | habías 191 | habíamos 192 | habíais 193 | habían 194 | hube 195 | hubiste 196 | hubo 197 | hubimos 198 | hubisteis 199 | hubieron 200 | hubiera 201 | hubieras 202 | hubiéramos 203 | hubierais 204 | hubieran 205 | hubiese 206 | hubieses 207 | hubiésemos 208 | hubieseis 209 | hubiesen 210 | habiendo 211 | habido 212 | habida 213 | habidos 214 | habidas 215 | soy 216 | eres 217 | es 218 | somos 219 | sois 220 | son 221 | sea 222 | seas 223 | seamos 224 | seáis 225 | sean 226 | seré 227 | serás 228 | será 229 | seremos 230 | seréis 231 | serán 232 | sería 233 | serías 234 | seríamos 235 | seríais 236 | serían 237 | era 238 | eras 239 | éramos 240 | erais 241 | eran 242 | fui 243 | fuiste 244 | fue 245 | fuimos 246 | fuisteis 247 | fueron 248 | fuera 249 | fueras 250 | fuéramos 251 | fuerais 252 | fueran 253 | fuese 254 | fueses 255 | fuésemos 256 | fueseis 257 | fuesen 258 | sintiendo 259 | sentido 260 | sentida 261 | sentidos 262 | sentidas 263 | siente 264 | sentid 265 | tengo 266 | tienes 267 | tiene 268 | tenemos 269 | tenéis 270 | tienen 271 | tenga 272 | tengas 273 | tengamos 274 | tengáis 275 | tengan 276 | tendré 277 | tendrás 278 | tendrá 279 | tendremos 280 | tendréis 281 | tendrán 282 | tendría 283 | tendrías 284 | tendríamos 285 | tendríais 286 | tendrían 287 | tenía 288 | tenías 289 | teníamos 290 | teníais 291 | tenían 292 | tuve 293 | tuviste 294 | tuvo 295 | tuvimos 296 | tuvisteis 297 | tuvieron 298 | tuviera 299 | tuvieras 300 | tuviéramos 301 | tuvierais 302 | tuvieran 303 | tuviese 304 | tuvieses 305 | tuviésemos 306 | tuvieseis 307 | tuviesen 308 | teniendo 309 | tenido 310 | tenida 311 | tenidos 312 | tenidas 313 | tened 314 | -------------------------------------------------------------------------------- /databasic/logic/stopwords/welsh: -------------------------------------------------------------------------------- 1 | fi 2 | mi 3 | fy 4 | hunan 5 | byddaf 6 | fyddaf 7 | i 8 | ni 9 | ein 10 | hunain 11 | byddwn 12 | fyddwn 13 | chi 14 | byddwch 15 | fyddwch 16 | eich 17 | ti 18 | byddi 19 | fyddi 20 | dy 21 | fe 22 | ef 23 | ei 24 | hi 25 | nhw 26 | wy 27 | eu 28 | beth 29 | a 30 | pwy 31 | hwn 32 | hon 33 | hyn 34 | hwnnw 35 | honno 36 | hynny 37 | yn 38 | roeddwn 39 | oeddwn 40 | roedd 41 | oedd 42 | roeddech 43 | oeddech 44 | roeddent 45 | oeddent 46 | bod 47 | gennyf 48 | gen 49 | ganddo 50 | ganddi 51 | gan 52 | gennych 53 | ganddynt 54 | ganddyn 55 | gwneud 56 | gwnes 57 | gwnest 58 | gwnaeth 59 | gwnaethant 60 | y 61 | yr 62 | a 63 | ac 64 | ond 65 | os 66 | neu 67 | achos 68 | oherwydd 69 | am 70 | fel 71 | tan 72 | nes 73 | tra 74 | yn 75 | gan 76 | ar 77 | gyda 78 | gydag 79 | efoynghylch 80 | erbyn 81 | rhwng 82 | mewn 83 | trwy 84 | drwy 85 | ystod 86 | cyn 87 | ôl 88 | uwchben 89 | islaw 90 | i 91 | o 92 | fyny 93 | lan 94 | lawr 95 | allan 96 | ymlaen 97 | ffwrdd 98 | dros 99 | an 100 | eto 101 | pellach 102 | yna 103 | ma 104 | unwaith 105 | pryd 106 | ble 107 | lle 108 | pam 109 | sut 110 | pob 111 | unrhyw 112 | ddau 113 | un 114 | ychydig 115 | mwy 116 | fwy 117 | mwyaf 118 | fwyaf 119 | arall 120 | eraill 121 | rhai 122 | a 123 | dim 124 | ddim 125 | felly 126 | a 127 | hefyd 128 | iawn 129 | gall 130 | gallu 131 | peidiwch 132 | paid 133 | â 134 | dylwn 135 | ddylwn 136 | dylet 137 | ddylet 138 | dylai 139 | ddylai 140 | dylent 141 | ddylent 142 | dylech 143 | ddylech 144 | nawr 145 | ethu 146 | heb 147 | efallai 148 | falle 149 | rhaid 150 | peidio 151 | angen 152 | faswn 153 | fasai 154 | fasech 155 | fasent 156 | al 157 | bydd 158 | cael 159 | di 160 | fod 161 | holl 162 | ir 163 | idl 164 | mae 165 | n 166 | nid 167 | on 168 | n 169 | pan 170 | r 171 | rwyn 172 | rwy 173 | sy 174 | sydd 175 | syn 176 | wedi 177 | yw -------------------------------------------------------------------------------- /databasic/logic/stopwords/welsh_english: -------------------------------------------------------------------------------- 1 | i 2 | me 3 | my 4 | myself 5 | we 6 | our 7 | ours 8 | ourselves 9 | you 10 | your 11 | yours 12 | yourself 13 | yourselves 14 | he 15 | him 16 | his 17 | himself 18 | she 19 | her 20 | hers 21 | herself 22 | it 23 | its 24 | itself 25 | they 26 | them 27 | their 28 | theirs 29 | themselves 30 | what 31 | which 32 | who 33 | whom 34 | this 35 | that 36 | these 37 | those 38 | am 39 | is 40 | are 41 | was 42 | were 43 | be 44 | been 45 | being 46 | have 47 | has 48 | had 49 | having 50 | do 51 | does 52 | did 53 | doing 54 | a 55 | an 56 | the 57 | and 58 | but 59 | if 60 | or 61 | because 62 | as 63 | until 64 | while 65 | of 66 | at 67 | by 68 | for 69 | with 70 | about 71 | against 72 | between 73 | into 74 | through 75 | during 76 | before 77 | after 78 | above 79 | below 80 | to 81 | from 82 | up 83 | down 84 | in 85 | out 86 | on 87 | off 88 | over 89 | under 90 | again 91 | further 92 | then 93 | once 94 | here 95 | there 96 | when 97 | where 98 | why 99 | how 100 | all 101 | any 102 | both 103 | each 104 | few 105 | more 106 | most 107 | other 108 | some 109 | such 110 | no 111 | nor 112 | not 113 | only 114 | own 115 | same 116 | so 117 | than 118 | too 119 | very 120 | s 121 | t 122 | can 123 | will 124 | just 125 | don 126 | should 127 | now 128 | -------------------------------------------------------------------------------- /databasic/logic/test/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/logic/test/__init__.py -------------------------------------------------------------------------------- /databasic/logic/test/connectthedotsbigdatatest.py: -------------------------------------------------------------------------------- 1 | import math, networkx as nx, timeit, unittest 2 | 3 | class ConnectTheDotsBigDataTest(unittest.TestCase): 4 | """ 5 | Benchmarking suite for ConnectTheDots (large datasets) 6 | """ 7 | 8 | def test_bc_runtime(self): 9 | """ 10 | Test time needed to calculate betweenness centrality 11 | """ 12 | 13 | TEST_CASES = [] # add (V, E) tuples 14 | 15 | NUM_TRIALS = 10 16 | 17 | def generate_graph(V, E): 18 | """ 19 | Return a random Barabasi-Albert graph with V nodes and E edges 20 | """ 21 | m = (V - math.sqrt(V ** 2 - 4 * E)) / 2 22 | return nx.barabasi_albert_graph(V, int(m)) 23 | 24 | def calculate_bc(G): 25 | """ 26 | Calculate betweenness centrality for graph G 27 | """ 28 | return nx.betweenness_centrality(G) 29 | 30 | if len(TEST_CASES) > 0: 31 | print('\n\n[ Runtime ]\n') 32 | 33 | for (V, E) in TEST_CASES: 34 | print('V = ' + str(V) + ', E = ' + str(E) + '\n') 35 | G = generate_graph(V, E) 36 | for i in range(NUM_TRIALS): 37 | start = timeit.default_timer() 38 | calculate_bc(G) 39 | stop = timeit.default_timer() 40 | print(stop - start) 41 | print('') 42 | 43 | def test_bc_estimation(self): 44 | """ 45 | Test accuracy of different k-values for betweenness centrality estimation 46 | """ 47 | 48 | TEST_CASES = [] # add (V, E, k) tuples 49 | 50 | NUM_TRIALS = 1 51 | 52 | def generate_graph(V, E): 53 | """ 54 | Return a random Barabasi-Albert graph with V nodes and E edges 55 | """ 56 | m = (V - math.sqrt(V ** 2 - 4 * E)) / 2 57 | return nx.barabasi_albert_graph(V, int(m)) 58 | 59 | def calculate_bc(G, k=None): 60 | """ 61 | Calculate betweenness centrality for graph G using k pivots 62 | """ 63 | return nx.betweenness_centrality(G, k) 64 | 65 | def round_float(n): 66 | """ 67 | Return string representation of float n rounded to six decimal places 68 | """ 69 | return '{:f}'.format(n) 70 | 71 | def error_pct(error, actual): 72 | """ 73 | Return string representation of error % of estimate from actual 74 | """ 75 | if actual > 0: 76 | return '{:.1%}'.format(error / actual) 77 | else: 78 | return '--' 79 | 80 | if len(TEST_CASES) > 0: 81 | print('\n\n[ Estimation ]\n') 82 | 83 | for (V, E, k) in TEST_CASES: 84 | print('V = ' + str(V) + ', E = ' + str(E) + ', k = ' + str(k) + '\n') 85 | G = generate_graph(V, E) 86 | bc = calculate_bc(G) 87 | 88 | for i in range(NUM_TRIALS): 89 | # estimate = calculate_bc(G, key) 90 | # print 'node estimate actual error % error' 91 | # print '---- -------- -------- -------- --------' 92 | # for key, val in estimate.iteritems(): 93 | # error = abs(bc[key] - val) 94 | # print ' '.join(['{:04}'.format(key), round_float(val), round_float(bc[key]), round_float(error), error_pct(error, bc[key])]) 95 | # print '' 96 | 97 | start = timeit.default_timer() 98 | estimate = calculate_bc(G, k) 99 | stop = timeit.default_timer() 100 | runtime = stop - start 101 | max_error = 0 102 | max_error_pct = 0 103 | for key, val in estimate.items(): 104 | error = abs(bc[key] - val) 105 | max_error = max(max_error, error) 106 | if bc[key] > 0: 107 | max_error_pct = max(max_error_pct, error / bc[key]) 108 | print(', ' .join([round_float(max_error), '{:.1%}'.format(max_error_pct), str(runtime)])) 109 | print('') 110 | -------------------------------------------------------------------------------- /databasic/logic/test/dbtest.py: -------------------------------------------------------------------------------- 1 | import unittest, logging, time, codecs, os 2 | import databasic.logic.db as db 3 | 4 | class MongoHandlerTest(unittest.TestCase): 5 | 6 | def setUp(self): 7 | self._mongo = db.MongoHandler('localhost','databasic-test') 8 | self._collection = 'test' 9 | 10 | def test_results_for_sample(self): 11 | sample_id = 'test-sample-data' 12 | self._mongo._db[self._collection].save({'sample_id': sample_id}) 13 | existing_record = self._mongo.results_for_sample(self._collection,sample_id) 14 | self.assertIsNotNone(existing_record) 15 | missing_record = self._mongo.results_for_sample(self._collection,'not the sample data') 16 | self.assertIsNone(missing_record) 17 | -------------------------------------------------------------------------------- /databasic/logic/test/filehandlertest.py: -------------------------------------------------------------------------------- 1 | import unittest, logging, time, codecs, os 2 | import databasic.logic.filehandler as filehandler 3 | 4 | class FileHandlerTest(unittest.TestCase): 5 | 6 | def setUp(self): 7 | self._fixtures_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),"fixtures") 8 | 9 | def test_write_to_temp_file(self): 10 | timestr = time.strftime("%Y%m%d-%H%M%S") 11 | data_to_write = "this is some data on %s" % timestr 12 | file_path = filehandler.write_to_temp_file(data_to_write) 13 | logging.info("Wrote to %s" % file_path) 14 | with codecs.open(file_path, 'r', filehandler.ENCODING_UTF_8) as f: 15 | data_as_written = f.read() 16 | self.assertEqual(data_as_written, data_to_write) 17 | 18 | def test_convert_to_txt_utf8(self): 19 | fixture_path = os.path.join(self._fixtures_dir,'utf-8.txt') 20 | text = filehandler.convert_to_txt(fixture_path) 21 | self.assertEqual(len(text),7159) 22 | 23 | def test_convert_to_txt_latin1(self): 24 | fixture_path = os.path.join(self._fixtures_dir,'latin-1.txt') 25 | text = filehandler.convert_to_txt(fixture_path) 26 | self.assertEqual(len(text),860) 27 | 28 | def test_docx_to_txt(self): 29 | fixture_path = os.path.join(self._fixtures_dir,'demo.docx') 30 | text = filehandler._docx_to_txt(fixture_path) 31 | self.assertEqual(len(text),9031) 32 | valid_utf8 = True 33 | try: 34 | text.decode(filehandler.ENCODING_UTF_8) 35 | except UnicodeDecodeError: 36 | valid_utf8 = False 37 | self.assertTrue(valid_utf8) 38 | 39 | def test_convert_to_csv(self): 40 | fixture_path = os.path.join(self._fixtures_dir,'HowAmericaInjuresItself_FromNEISS.xlsx') 41 | results = filehandler.convert_to_csv(fixture_path) 42 | self.assertEqual(len(results),1) 43 | 44 | def test_open_with_correct_encoding(self): 45 | fixture_path = os.path.join(self._fixtures_dir,'latin-1.txt') 46 | encoding, file_handle, content = filehandler.open_with_correct_encoding(fixture_path) 47 | self.assertEqual(encoding,filehandler.ENCODING_LATIN_1) 48 | fixture_path = os.path.join(self._fixtures_dir,'utf-8.txt') 49 | encoding, file_handle, content = filehandler.open_with_correct_encoding(fixture_path) 50 | self.assertEqual(encoding,filehandler.ENCODING_UTF_8) 51 | 52 | def test_convert_to_utf8(self): 53 | fixture_path = os.path.join(self._fixtures_dir,'latin-1.txt') 54 | encoding, file_handle, content = filehandler.open_with_correct_encoding(fixture_path) 55 | self.assertEqual(encoding,filehandler.ENCODING_LATIN_1) 56 | temp_utf8_file_path = filehandler.convert_to_utf8(fixture_path) 57 | encoding, file_handle, content = filehandler.open_with_correct_encoding(temp_utf8_file_path) 58 | self.assertEqual(encoding,filehandler.ENCODING_UTF_8) 59 | -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/HowAmericaInjuresItself_FromNEISS.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/logic/test/fixtures/HowAmericaInjuresItself_FromNEISS.xlsx -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/airline-routes-centralities.csv: -------------------------------------------------------------------------------- 1 | airport,centrality 2 | ANC,0.07248270694418962 3 | LAX,0.06520775890690797 4 | CDG,0.061935884994422506 5 | DXB,0.056487934217391726 6 | FRA,0.0510857090256466 7 | PEK,0.04956926032160246 8 | AMS,0.049262447233646936 9 | SEA,0.048107633012432836 10 | ORD,0.04793981590845767 11 | YYZ,0.04265081111920802 12 | IST,0.041737706148133026 13 | GRU,0.0403836533591574 14 | LHR,0.037209226269353295 15 | NRT,0.035934521323980034 16 | SYD,0.032664612724846755 17 | BNE,0.03182301879929612 18 | SIN,0.031149410101313255 19 | DME,0.029360421912011474 20 | ATL,0.02903160794540127 21 | DFW,0.028870743987937385 22 | YUL,0.028037951925789027 23 | HKG,0.027481931703755215 24 | CPH,0.02691586320630594 25 | ICN,0.02688842428345686 26 | DEN,0.026365352779184156 27 | JFK,0.024934006576947318 28 | MIA,0.024857065279251096 29 | BOG,0.024216239790822613 30 | JNB,0.022432273961953058 31 | IAH,0.022373738874024277 32 | PVG,0.022165087667730857 33 | BKK,0.02208956551356009 34 | MAD,0.021700004447230307 35 | MNL,0.019569313524901693 36 | SFJ,0.0191371538587603 37 | YVR,0.019010143518405555 38 | ARN,0.018903048681067736 39 | JED,0.01877695186944175 40 | BET,0.018153228958766206 41 | KUL,0.01812376640233782 -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/demo.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/logic/test/fixtures/demo.docx -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/handshake-problem.csv: -------------------------------------------------------------------------------- 1 | Alice,Bob 2 | Alice,Carol 3 | Alice,Dave 4 | Alice,Eve 5 | Bob,Carol 6 | Bob,Dave 7 | Bob,Eve 8 | Carol,Dave 9 | Carol,Eve 10 | Dave,Eve -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/invalid-graph.csv: -------------------------------------------------------------------------------- 1 | from,to,random,extra,columns 2 | 0,1,a,b,c 3 | 0,2,a,b,c 4 | 0,3,a,b,c 5 | 1,2,a,b,c 6 | 2,4,a,b,c 7 | 3,4,a,b,c 8 | 3,5,a,b,c 9 | 5,6,a,b,c -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/latin-1.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/logic/test/fixtures/latin-1.txt -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/simple-network.csv: -------------------------------------------------------------------------------- 1 | from,to 2 | A,C 3 | B,C 4 | C,D 5 | C,E -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/southern-women.csv: -------------------------------------------------------------------------------- 1 | name,event 2 | EVELYN,E1 3 | EVELYN,E2 4 | EVELYN,E3 5 | EVELYN,E4 6 | EVELYN,E5 7 | EVELYN,E6 8 | EVELYN,E8 9 | EVELYN,E9 10 | LAURA,E1 11 | LAURA,E2 12 | LAURA,E3 13 | LAURA,E5 14 | LAURA,E6 15 | LAURA,E7 16 | LAURA,E8 17 | THERESA,E2 18 | THERESA,E3 19 | THERESA,E4 20 | THERESA,E5 21 | THERESA,E6 22 | THERESA,E7 23 | THERESA,E8 24 | THERESA,E9 25 | BRENDA,E1 26 | BRENDA,E3 27 | BRENDA,E4 28 | BRENDA,E5 29 | BRENDA,E6 30 | BRENDA,E7 31 | BRENDA,E8 32 | CHARLOTTE,E3 33 | CHARLOTTE,E4 34 | CHARLOTTE,E5 35 | CHARLOTTE,E7 36 | FRANCES,E3 37 | FRANCES,E5 38 | FRANCES,E6 39 | FRANCES,E8 40 | ELEANOR,E5 41 | ELEANOR,E6 42 | ELEANOR,E7 43 | ELEANOR,E8 44 | PEARL,E6 45 | PEARL,E8 46 | PEARL,E9 47 | RUTH,E5 48 | RUTH,E7 49 | RUTH,E8 50 | RUTH,E9 51 | VERNE,E7 52 | VERNE,E8 53 | VERNE,E9 54 | VERNE,E12 55 | MYRNA,E8 56 | MYRNA,E9 57 | MYRNA,E10 58 | MYRNA,E12 59 | KATHERINE,E8 60 | KATHERINE,E9 61 | KATHERINE,E10 62 | KATHERINE,E12 63 | KATHERINE,E13 64 | KATHERINE,E14 65 | SYLVIA,E7 66 | SYLVIA,E8 67 | SYLVIA,E9 68 | SYLVIA,E10 69 | SYLVIA,E12 70 | SYLVIA,E13 71 | SYLVIA,E14 72 | NORA,E6 73 | NORA,E7 74 | NORA,E9 75 | NORA,E10 76 | NORA,E11 77 | NORA,E12 78 | NORA,E13 79 | NORA,E14 80 | HELEN,E7 81 | HELEN,E8 82 | HELEN,E10 83 | HELEN,E11 84 | HELEN,E12 85 | HELEN,E13 86 | HELEN,E14 87 | DOROTHY,E8 88 | DOROTHY,E9 89 | DOROTHY,E10 90 | DOROTHY,E12 91 | OLIVIA,E9 92 | OLIVIA,E11 93 | FLORA,E9 94 | FLORA,E11 95 | -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/trailing-comma.csv: -------------------------------------------------------------------------------- 1 | "first column","second one", 2 | 2015, 45, 3 | 2016, 87, 4 | 2017, 145, -------------------------------------------------------------------------------- /databasic/logic/test/fixtures/zachary-karate-club.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/logic/test/fixtures/zachary-karate-club.xlsx -------------------------------------------------------------------------------- /databasic/logic/test/wordhandlertest.py: -------------------------------------------------------------------------------- 1 | import unittest, logging, time, codecs, os 2 | import databasic.logic.wordhandler as wordhandler 3 | import databasic.logic.filehandler as filehandler 4 | 5 | class WordHandlerTest(unittest.TestCase): 6 | 7 | def setUp(self): 8 | self._fixtures_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),"fixtures") 9 | 10 | def test_too_many_counts(self): 11 | fixture_path = os.path.join(self._fixtures_dir,'22kAmazonGameReview.txt') 12 | words = filehandler.convert_to_txt(fixture_path) 13 | counts = wordhandler.get_word_counts(words,True,True,'english') 14 | self.assertEqual(len(counts[0]),wordhandler.MAX_ITEMS) 15 | self.assertEqual(len(counts[1]),wordhandler.MAX_ITEMS) 16 | self.assertEqual(len(counts[2]),wordhandler.MAX_ITEMS) 17 | -------------------------------------------------------------------------------- /databasic/logic/test/wtfcsvstattest.py: -------------------------------------------------------------------------------- 1 | import unittest, logging, time, codecs, os 2 | import databasic.logic.wtfcsvstat as wtfcsvstat 3 | import databasic.logic.filehandler as filehandler 4 | 5 | class WTFCSVStatTest(unittest.TestCase): 6 | 7 | def setUp(self): 8 | self._fixtures_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)),"fixtures") 9 | 10 | def test_get_summary_from_csv(self): 11 | test_data_path = os.path.join(self._fixtures_dir,'somerville-tree-details.csv') 12 | results = wtfcsvstat.get_summary(test_data_path) 13 | self.assertEqual(len(results['columns']), 43) 14 | self.assertEqual(results['row_count'], 13882) 15 | 16 | def test_get_summary_from_xls(self): 17 | fixture_path = os.path.join(self._fixtures_dir,'HowAmericaInjuresItself_FromNEISS.xlsx') 18 | csv_file = filehandler.convert_to_csv(fixture_path)[0] 19 | results = wtfcsvstat.get_summary(csv_file) 20 | self.assertEqual(len(results['columns']), 19) 21 | self.assertEqual(results['row_count'], 26303) 22 | 23 | def test_trailing_comma(self): 24 | test_data_path = os.path.join(self._fixtures_dir,'trailing-comma.csv') 25 | results = wtfcsvstat.get_summary(test_data_path) 26 | self.assertEqual(len(results['columns']), 2) 27 | self.assertEqual(results['row_count'], 3) 28 | -------------------------------------------------------------------------------- /databasic/logic/textanalysis.py: -------------------------------------------------------------------------------- 1 | import textmining 2 | from scipy import spatial 3 | import re 4 | import string 5 | import databasic.logic.stopwords as stopwords 6 | from databasic import NLTK_STOPWORDS_BY_LANGUAGE 7 | 8 | 9 | 10 | def _databasic_tokenize(text, ignore_case=True, remove_stopwords=True, lang='english'): 11 | words = re.findall(r"[\w'-]+|[.,!?;]", text, re.UNICODE) 12 | if ignore_case: 13 | words = [w.lower() for w in words] 14 | if remove_stopwords: 15 | stopwordlist = stopwords._custom_stopwords_list(lang) 16 | 17 | return [w for w in words if (w not in string.punctuation and w not in stopwordlist)] 18 | 19 | def term_document_matrix(texts, current_lang_code): 20 | lang = NLTK_STOPWORDS_BY_LANGUAGE.get(current_lang_code, "english") 21 | term_doc_matrix = textmining.TermDocumentMatrix(tokenizer=lambda text:_databasic_tokenize(text, lang=lang)) 22 | for t in texts: 23 | term_doc_matrix.add_doc(t) 24 | return term_doc_matrix 25 | 26 | 27 | def common_and_unique_word_freqs(texts, current_lang_code): 28 | word_count_d1 = len(texts[0].split()) 29 | word_count_d2 = len(texts[1].split()) 30 | tdm = term_document_matrix(texts, current_lang_code) 31 | # get the most common used words, sorted by freq 32 | common_rows = tdm.rows(cutoff=2) 33 | common_terms = next(common_rows) 34 | common_d1_freqs = next(common_rows) 35 | common_d2_freqs = next(common_rows) 36 | total_uses = [t1 + t2 for t1, t2 in zip(common_d1_freqs, common_d2_freqs)] 37 | common_word_freqs = list(zip(total_uses, common_terms)) 38 | common_word_freqs.sort(reverse=True) 39 | # get word counts of common terms in each document 40 | common_counts = [list(zip(common_d1_freqs, common_terms)), list(zip(common_d2_freqs, common_terms))] 41 | common_counts[0].sort(reverse=True) 42 | common_counts[1].sort(reverse=True) 43 | # get all the rows for unique-to-doc calculations 44 | all_rows = tdm.rows(cutoff=0) 45 | all_terms = next(all_rows) 46 | all_d1_freqs = next(all_rows) 47 | all_d2_freqs = next(all_rows) 48 | # get the doc1 words 49 | d1 = [(f1, t) for t, f1 in zip(all_terms, all_d1_freqs) if f1 > 0] 50 | d1.sort(reverse=True) 51 | # get the doc2 words 52 | d2 = [(f2, t) for t, f2 in zip(all_terms, all_d2_freqs) if f2 > 0] 53 | d2.sort(reverse=True) 54 | # get the unique doc1 words 55 | unique_to_d1 = [(f1, t) for t, f1, f2 in zip(all_terms, all_d1_freqs, all_d2_freqs) if f2 == 0] 56 | unique_to_d1.sort(reverse=True) 57 | # get the unique doc2 words 58 | unique_to_d2 = [(f2, t) for t, f1, f2 in zip(all_terms, all_d1_freqs, all_d2_freqs) if f1 == 0] 59 | unique_to_d2.sort(reverse=True) 60 | # compute cosine similarity too 61 | cosine_similarity = (1 - spatial.distance.cosine(all_d1_freqs, all_d2_freqs)) 62 | 63 | # stitch it together to return the data 64 | return {'common': common_word_freqs, 'common_counts': common_counts, 'doc1': d1, 'doc2': d2, 65 | 'doc1unique': unique_to_d1, 'doc2unique': unique_to_d2, 66 | 'doc1total': word_count_d1, 'doc2total': word_count_d2, 67 | 'cosine_similarity': cosine_similarity} 68 | -------------------------------------------------------------------------------- /databasic/logic/wordhandler.py: -------------------------------------------------------------------------------- 1 | import nltk 2 | import re 3 | import string 4 | import logging 5 | from operator import itemgetter 6 | from nltk import FreqDist 7 | 8 | 9 | import databasic.logic.stopwords as stopwords 10 | 11 | DEFAULT_TEXT = 'I am Sam\nSam I am\nThat Sam-I-am!\nThat Sam-I-am!\nI do not like that Sam-I-am!\nDo you like \ngreen eggs and ham?\nI do not like them, Sam-I-am.\nI do not like\ngreen eggs and ham.\nWould you like them \nhere or there?\nI would not like them\nhere or there.\nI would not like them anywhere.' 12 | 13 | logger = logging.getLogger(__name__) 14 | 15 | MAX_ITEMS = 10000 16 | 17 | 18 | def get_word_counts(text=None, ignore_case=True, ignore_stop_words=True, stopwords_language='english', get_bigrams=True, get_trigrams=True): 19 | text = DEFAULT_TEXT if text is None else text 20 | words = _create_words(text, ignore_case) 21 | 22 | total_word_count = len(words) 23 | unique_words = _sort_count_list(_count_words(words, ignore_stop_words, stopwords_language))[0:MAX_ITEMS] 24 | 25 | if get_bigrams: 26 | bigrams = _sort_count_list(_count_bigrams(words))[0:MAX_ITEMS] 27 | else: 28 | bigrams = [] 29 | 30 | if get_trigrams: 31 | trigrams = _sort_count_list(_count_trigrams(words))[0:MAX_ITEMS] 32 | else: 33 | trigrams = [] 34 | 35 | logger.debug(" %d unique_words, %d bigrams, %d trigrams, %d total words" % (len(unique_words),len(bigrams), len(trigrams), total_word_count)) 36 | return {"unique_words":unique_words, "bigrams" : bigrams, "trigrams":trigrams, "total_word_count":total_word_count} 37 | 38 | 39 | def _create_words(text, ignore_case): 40 | words = re.findall(r"[\w'-]+|[.,!?;]", text, re.UNICODE) 41 | if ignore_case: 42 | words = [w.lower() for w in words] 43 | return [w for w in words if w not in string.punctuation] 44 | 45 | 46 | def _sort_count_list(freq_dist): 47 | items = list(freq_dist.items()) 48 | return sorted(items, key=itemgetter(1), reverse=True) 49 | 50 | 51 | def _count_words(words, ignore_stop_words, stopwords_language): 52 | logger.error(stopwords_language) 53 | fdist = FreqDist(words) 54 | 55 | # remove stopwords here rather than in corpus text for speed 56 | if ignore_stop_words: 57 | logger.debug("I AM IN IGNORE STOPWORDS language is {}".format(stopwords_language)) 58 | fdist = stopwords.remove_from_freq_dist(fdist, stopwords_language) 59 | if stopwords_language == 'danish': 60 | # our partner advised this is necessary for Danish 61 | fdist = stopwords.remove_from_freq_dist(fdist, 'english') 62 | return fdist 63 | 64 | 65 | def _count_bigrams(words): 66 | bigrams = nltk.bigrams(words) 67 | return nltk.FreqDist(bigrams) 68 | 69 | 70 | def _count_trigrams(words): 71 | trigrams = nltk.trigrams(words) 72 | return nltk.FreqDist(trigrams) 73 | -------------------------------------------------------------------------------- /databasic/mail.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from flask_mail import Message 3 | 4 | from databasic import app, mail 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | DEFAULT_SENDER = app.config.get('MAIL_USERNAME') 9 | 10 | 11 | def send_email(sender, recipients, subject, message): 12 | logger.debug('Sending mail '+sender+':'+subject) 13 | msg = Message(subject, 14 | sender=sender, 15 | recipients=recipients) 16 | msg.body = message 17 | mail.send(msg) 18 | 19 | ''' 20 | def send_html_email(subject, recipients, text_body, html_body): 21 | msg = Message(subject, sender=DEFAULT_SENDER, recipients=recipients) 22 | msg.body = text_body 23 | msg.html = html_body 24 | mail.send(msg) 25 | ''' 26 | -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/cy/Connect the Dots Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/cy/Connect the Dots Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/cy/SameDiff Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/cy/SameDiff Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/cy/WTFcsv Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/cy/WTFcsv Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/cy/WordCounter Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/cy/WordCounter Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/da/Connect the Dots Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/da/Connect the Dots Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/da/SameDiff Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/da/SameDiff Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/da/WTFcsv Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/da/WTFcsv Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/da/WordCounter Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/da/WordCounter Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/Build a Data Sculpture.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/Build a Data Sculpture.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/Connect the Dots Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/Connect the Dots Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/Data Diary.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/Data Diary.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/Embody a Dataset.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/Embody a Dataset.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/Evaluating Your Story.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/Evaluating Your Story.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/Finding a story.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/Finding a story.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/Make a (Data) Scene.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/Make a (Data) Scene.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/SameDiff Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/SameDiff Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/Sketch a Visual Word Web.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/Sketch a Visual Word Web.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/WTFcsv Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/WTFcsv Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en/WordCounter Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en/WordCounter Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en_CY/Connect the Dots Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en_CY/Connect the Dots Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en_CY/SameDiff Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en_CY/SameDiff Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en_CY/WTFcsv Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en_CY/WTFcsv Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/en_CY/WordCounter Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/en_CY/WordCounter Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/es/Connect the Dots Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/es/Connect the Dots Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/es/SameDiff Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/es/SameDiff Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/es/WTFcsv Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/es/WTFcsv Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/es/WordCounter Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/es/WordCounter Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/pt/Connect the Dots Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/pt/Connect the Dots Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/pt/SameDiff Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/pt/SameDiff Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/pt/WTFcsv Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/pt/WTFcsv Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-guides/pt/WordCounter Activity Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-guides/pt/WordCounter Activity Guide.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/cy/Infographic Remix Cards.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/cy/Infographic Remix Cards.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/cy/Picking a Technique.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/cy/Picking a Technique.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/cy/Way_To_go_cym.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/cy/Way_To_go_cym.png -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/da/Picking a Technique.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/da/Picking a Technique.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/da/Vurder din fortælling - Evaluate Your Story.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/da/Vurder din fortælling - Evaluate Your Story.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en/Infographic Remix Cards.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en/Infographic Remix Cards.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en/Picking a Technique.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en/Picking a Technique.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en/Storytelling Techniques.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en/Storytelling Techniques.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en/data sculpture - MIT costs - rev3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en/data sculpture - MIT costs - rev3.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en/data sculpture - happiness - rev2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en/data sculpture - happiness - rev2.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en/data sculpture - ice cream - rev2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en/data sculpture - ice cream - rev2.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en_CY/Infographic Remix Cards.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en_CY/Infographic Remix Cards.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en_CY/Picking a Technique.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en_CY/Picking a Technique.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en_CY/Storytelling Techniques.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en_CY/Storytelling Techniques.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en_CY/Way_To_go_ENG.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en_CY/Way_To_go_ENG.png -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en_CY/data sculpture - MIT costs - rev3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en_CY/data sculpture - MIT costs - rev3.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en_CY/data sculpture - happiness - rev2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en_CY/data sculpture - happiness - rev2.pdf -------------------------------------------------------------------------------- /databasic/static/files/activity-materials/en_CY/data sculpture - ice cream - rev2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/activity-materials/en_CY/data sculpture - ice cream - rev2.pdf -------------------------------------------------------------------------------- /databasic/static/files/examples/storybook1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/files/examples/storybook1.pdf -------------------------------------------------------------------------------- /databasic/static/files/user-templates/en/ctd-template.csv: -------------------------------------------------------------------------------- 1 | source,target 2 | Alice,Bob 3 | Rahul,Catherine 4 | Catherine ,Alice 5 | Bob,Rodrigo 6 | Orlando,Adiya 7 | Adiya ,Catherine 8 | Rahul,Gus 9 | Cosmo,Bob -------------------------------------------------------------------------------- /databasic/static/files/user-templates/es/ctd-template.csv: -------------------------------------------------------------------------------- 1 | origen,objetivo 2 | Andres,Roberto 3 | Rahul,Catherine 4 | Catherine,Andres 5 | Roberto,Rodrigo 6 | Orlando,Adiya 7 | Adiya,Catherine 8 | Rahul,Augusto 9 | Cosmo,Roberto -------------------------------------------------------------------------------- /databasic/static/files/user-templates/pt/ctd-template.csv: -------------------------------------------------------------------------------- 1 | origem,alvo 2 | Andres,Agostinho 3 | Rahul,Catherine 4 | Catherine,Andres 5 | Agostinho,Rodrigo 6 | Orlando,Adiya 7 | Adiya,Catherine 8 | Rahul,Agostinho 9 | Cosmo,Agostinho -------------------------------------------------------------------------------- /databasic/static/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /databasic/static/fonts/MyFontsWebfontsKit.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | MyFonts Webfont Build ID 3120690, 2015-11-05T17:40:17-0500 4 | 5 | The fonts listed in this notice are subject to the End User License 6 | Agreement(s) entered into by the website owner. All other parties are 7 | explicitly restricted from using the Licensed Webfonts(s). 8 | 9 | You may obtain a valid license at the URLs below. 10 | 11 | Webfont: HalisGR-Light by Ahmet Altun 12 | URL: http://www.myfonts.com/fonts/ahmet-altun/halis-gr/light/ 13 | 14 | Webfont: HalisGR-Book by Ahmet Altun 15 | URL: http://www.myfonts.com/fonts/ahmet-altun/halis-gr/book/ 16 | 17 | Webfont: HalisGR-Medium by Ahmet Altun 18 | URL: http://www.myfonts.com/fonts/ahmet-altun/halis-gr/medium/ 19 | 20 | 21 | License: http://www.myfonts.com/viewlicense?type=web&buildid=3120690 22 | Licensed pageviews: 500,000 23 | Webfonts copyright: Copyright (c) 2012 by Ahmet Altun. All rights reserved. 24 | 25 | ? 2015 MyFonts Inc 26 | */ 27 | var protocol=document.location.protocol;"https:"!=protocol&&(protocol="http:");var browserName,browserVersion,webfontType;if("undefined"==typeof woffEnabled)var woffEnabled=!0;var svgEnabled=0,woff2Enabled=1;if("undefined"!=typeof customPath)var path=customPath;else{var scripts=document.getElementsByTagName("SCRIPT"),script=scripts[scripts.length-1].src;script.match("://")||"/"==script.charAt(0)||(script="./"+script),path=script.replace(/\\/g,"/").replace(/\/[^\/]*\/?$/,"")}var wfpath=path+"/webfonts/",browsers=[{regex:"MSIE (\\d+\\.\\d+)",versionRegex:"new Number(RegExp.$1)",type:[{version:9,type:"woff"},{version:5,type:"eot"}]},{regex:"Trident/(\\d+\\.\\d+); (.+)?rv:(\\d+\\.\\d+)",versionRegex:"new Number(RegExp.$3)",type:[{version:11,type:"woff"}]},{regex:"Firefox[/s](\\d+\\.\\d+)",versionRegex:"new Number(RegExp.$1)",type:[{version:3.6,type:"woff"},{version:3.5,type:"ttf"}]},{regex:"Edge/(\\d+\\.\\d+)",versionRegex:"new Number(RegExp.$1)",type:[{version:12,type:"woff"}]},{regex:"Chrome/(\\d+\\.\\d+)",versionRegex:"new Number(RegExp.$1)",type:[{version:36,type:"woff2"},{version:6,type:"woff"},{version:4,type:"ttf"}]},{regex:"Mozilla.*Android (\\d+\\.\\d+).*AppleWebKit.*Safari",versionRegex:"new Number(RegExp.$1)",type:[{version:4.1,type:"woff"},{version:3.1,type:"svg#wf"},{version:2.2,type:"ttf"}]},{regex:"Mozilla.*(iPhone|iPad).* OS (\\d+)_(\\d+).* AppleWebKit.*Safari",versionRegex:"new Number(RegExp.$2) + (new Number(RegExp.$3) / 10)",unhinted:!0,type:[{version:5,type:"woff"},{version:4.2,type:"ttf"},{version:1,type:"svg#wf"}]},{regex:"Mozilla.*(iPhone|iPad|BlackBerry).*AppleWebKit.*Safari",versionRegex:"1.0",type:[{version:1,type:"svg#wf"}]},{regex:"Version/(\\d+\\.\\d+)(\\.\\d+)? Safari/(\\d+\\.\\d+)",versionRegex:"new Number(RegExp.$1)",type:[{version:5.1,type:"woff"},{version:3.1,type:"ttf"}]},{regex:"Opera/(\\d+\\.\\d+)(.+)Version/(\\d+\\.\\d+)(\\.\\d+)?",versionRegex:"new Number(RegExp.$3)",type:[{version:24,type:"woff2"},{version:11.1,type:"woff"},{version:10.1,type:"ttf"}]}],browLen=browsers.length,suffix="",i=0;e:for(;browLen>i;i++){var regex=new RegExp(browsers[i].regex);if(regex.test(navigator.userAgent)){browserVersion=eval(browsers[i].versionRegex);var typeLen=browsers[i].type.length;for(j=0;j=browsers[i].type[j].version&&(1==browsers[i].unhinted&&(suffix="_unhinted"),webfontType=browsers[i].type[j].type,"woff"!=webfontType||woffEnabled)&&("woff2"!=webfontType||woff2Enabled)&&("svg#wf"!=webfontType||svgEnabled))break e}else webfontType="woff"}/(Macintosh|Android)/.test(navigator.userAgent)&&"svg#wf"!=webfontType&&(suffix="_unhinted");var head=document.getElementsByTagName("head")[0],stylesheet=document.createElement("style");stylesheet.setAttribute("type","text/css"),head.appendChild(stylesheet);for(var fonts=[{fontFamily:"HalisGR-Light",url:wfpath+"2F9E32_0"+suffix+"_0."+webfontType},{fontFamily:"HalisGR-Book",url:wfpath+"2F9E32_1"+suffix+"_0."+webfontType},{fontFamily:"HalisGR-Medium",url:wfpath+"2F9E32_2"+suffix+"_0."+webfontType}],len=fonts.length,css="",i=0;len>i;i++){var format="svg#wf"==webfontType?'format("svg")':"ttf"==webfontType?'format("truetype")':"eot"==webfontType?"":'format("'+webfontType+'")',css=css+("@font-face{font-family: "+fonts[i].fontFamily+";src:url("+fonts[i].url+")"+format+";");fonts[i].fontWeight&&(css+="font-weight: "+fonts[i].fontWeight+";"),fonts[i].fontStyle&&(css+="font-style: "+fonts[i].fontStyle+";"),css+="}"}stylesheet.styleSheet?stylesheet.styleSheet.cssText=css:stylesheet.innerHTML=css; -------------------------------------------------------------------------------- /databasic/static/fonts/avenir/AvenirNext-Bold.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/avenir/AvenirNext-Bold.eot -------------------------------------------------------------------------------- /databasic/static/fonts/avenir/AvenirNext-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/avenir/AvenirNext-Bold.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/avenir/AvenirNext-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/avenir/AvenirNext-Bold.woff -------------------------------------------------------------------------------- /databasic/static/fonts/avenir/AvenirNext-Bold.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/avenir/AvenirNext-Bold.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/avenir/AvenirNext-Regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/avenir/AvenirNext-Regular.eot -------------------------------------------------------------------------------- /databasic/static/fonts/avenir/AvenirNext-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/avenir/AvenirNext-Regular.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/avenir/AvenirNext-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/avenir/AvenirNext-Regular.woff -------------------------------------------------------------------------------- /databasic/static/fonts/avenir/AvenirNext-Regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/avenir/AvenirNext-Regular.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /databasic/static/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /databasic/static/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /databasic/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /databasic/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_0_0.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_0_0.eot -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_0_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_0_0.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_0_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_0_0.woff -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_0_0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_0_0.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_0_unhinted_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_0_unhinted_0.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_0_unhinted_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_0_unhinted_0.woff -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_0_unhinted_0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_0_unhinted_0.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_1_0.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_1_0.eot -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_1_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_1_0.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_1_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_1_0.woff -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_1_0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_1_0.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_1_unhinted_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_1_unhinted_0.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_1_unhinted_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_1_unhinted_0.woff -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_1_unhinted_0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_1_unhinted_0.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_2_0.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_2_0.eot -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_2_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_2_0.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_2_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_2_0.woff -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_2_0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_2_0.woff2 -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_2_unhinted_0.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_2_unhinted_0.ttf -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_2_unhinted_0.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_2_unhinted_0.woff -------------------------------------------------------------------------------- /databasic/static/fonts/webfonts/2F9E32_2_unhinted_0.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/fonts/webfonts/2F9E32_2_unhinted_0.woff2 -------------------------------------------------------------------------------- /databasic/static/img/background_tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/background_tile.png -------------------------------------------------------------------------------- /databasic/static/img/background_tile_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/background_tile_small.png -------------------------------------------------------------------------------- /databasic/static/img/background_tile_tiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/background_tile_tiny.png -------------------------------------------------------------------------------- /databasic/static/img/backgrounds/tiled_background_blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/backgrounds/tiled_background_blue.png -------------------------------------------------------------------------------- /databasic/static/img/backgrounds/tiled_background_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/backgrounds/tiled_background_green.png -------------------------------------------------------------------------------- /databasic/static/img/backgrounds/tiled_background_pink.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/backgrounds/tiled_background_pink.png -------------------------------------------------------------------------------- /databasic/static/img/backgrounds/tiled_background_red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/backgrounds/tiled_background_red.png -------------------------------------------------------------------------------- /databasic/static/img/backgrounds/tiled_background_yellow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/backgrounds/tiled_background_yellow.png -------------------------------------------------------------------------------- /databasic/static/img/ctd-sheet-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/ctd-sheet-thumbnail.png -------------------------------------------------------------------------------- /databasic/static/img/culture/analyzing-data-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/analyzing-data-1.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/analyzing-data-1@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/analyzing-data-1@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/analyzing-data-1@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/analyzing-data-1@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/analyzing-data-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/analyzing-data-2.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/analyzing-data-2@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/analyzing-data-2@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/analyzing-data-2@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/analyzing-data-2@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/arrow.png -------------------------------------------------------------------------------- /databasic/static/img/culture/asking-questions-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/asking-questions-1.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/asking-questions-1@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/asking-questions-1@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/asking-questions-1@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/asking-questions-1@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/asking-questions-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/asking-questions-2.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/asking-questions-2@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/asking-questions-2@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/asking-questions-2@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/asking-questions-2@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/coming-soon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/coming-soon.png -------------------------------------------------------------------------------- /databasic/static/img/culture/convince-me-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/convince-me-1.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/convince-me-1@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/convince-me-1@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/convince-me-1@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/convince-me-1@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/data-culture-project-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/data-culture-project-logo.png -------------------------------------------------------------------------------- /databasic/static/img/culture/data-culture-project-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/data-culture-project-logo@2x.png -------------------------------------------------------------------------------- /databasic/static/img/culture/data-culture-project-logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/data-culture-project-logo@3x.png -------------------------------------------------------------------------------- /databasic/static/img/culture/data-process-cy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/data-process-cy.png -------------------------------------------------------------------------------- /databasic/static/img/culture/data-process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/data-process.png -------------------------------------------------------------------------------- /databasic/static/img/culture/databasic-logo-white-transparent-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/databasic-logo-white-transparent-bg.png -------------------------------------------------------------------------------- /databasic/static/img/culture/databasic-logo-white-transparent-bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/databasic-logo-white-transparent-bg@2x.png -------------------------------------------------------------------------------- /databasic/static/img/culture/databasic-logo-white-transparent-bg@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/databasic-logo-white-transparent-bg@3x.png -------------------------------------------------------------------------------- /databasic/static/img/culture/databasic-right-decoration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/databasic-right-decoration.png -------------------------------------------------------------------------------- /databasic/static/img/culture/deconstruct-samples.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/deconstruct-samples.png -------------------------------------------------------------------------------- /databasic/static/img/culture/gathering-data-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/gathering-data-1.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/gathering-data-1@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/gathering-data-1@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/gathering-data-1@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/gathering-data-1@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/img-1102.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/img-1102.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/img-1102@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/img-1102@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/img-1102@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/img-1102@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/paper-spreadsheet-0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/paper-spreadsheet-0.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/paper-spreadsheet-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/paper-spreadsheet-1.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/paper-spreadsheet-welsh.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/paper-spreadsheet-welsh.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/remix-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/remix-1.png -------------------------------------------------------------------------------- /databasic/static/img/culture/remix-cards-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/remix-cards-thumbnail.png -------------------------------------------------------------------------------- /databasic/static/img/culture/remix-handout-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/remix-handout-thumbnail.png -------------------------------------------------------------------------------- /databasic/static/img/culture/remix-water-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/remix-water-thumbnail.png -------------------------------------------------------------------------------- /databasic/static/img/culture/sculpture-brazil.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/sculpture-brazil.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/sketch-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/sketch-1.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/sketch-1@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/sketch-1@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/sketch-1@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/sketch-1@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/telling-your-story-1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/telling-your-story-1.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/telling-your-story-1@2x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/telling-your-story-1@2x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/telling-your-story-1@3x.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/telling-your-story-1@3x.jpg -------------------------------------------------------------------------------- /databasic/static/img/culture/virtual-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/virtual-icon.png -------------------------------------------------------------------------------- /databasic/static/img/culture/word-web-drawing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/word-web-drawing.png -------------------------------------------------------------------------------- /databasic/static/img/culture/word-web-social-exclusion-pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/culture/word-web-social-exclusion-pt.png -------------------------------------------------------------------------------- /databasic/static/img/data_basic_logo_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/data_basic_logo_128.png -------------------------------------------------------------------------------- /databasic/static/img/data_basic_logo_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/data_basic_logo_512.png -------------------------------------------------------------------------------- /databasic/static/img/databasic-logo-square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/databasic-logo-square.png -------------------------------------------------------------------------------- /databasic/static/img/icons/favicon-152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/icons/favicon-152.png -------------------------------------------------------------------------------- /databasic/static/img/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/icons/favicon.ico -------------------------------------------------------------------------------- /databasic/static/img/logos/MIT-logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | MIT large white and white logo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /databasic/static/img/logos/connectthedots_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/connectthedots_white.png -------------------------------------------------------------------------------- /databasic/static/img/logos/ctd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/ctd.png -------------------------------------------------------------------------------- /databasic/static/img/logos/ctd@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/ctd@2x.png -------------------------------------------------------------------------------- /databasic/static/img/logos/databasic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/databasic.png -------------------------------------------------------------------------------- /databasic/static/img/logos/databasic_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/databasic_white.png -------------------------------------------------------------------------------- /databasic/static/img/logos/el-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/el-large.png -------------------------------------------------------------------------------- /databasic/static/img/logos/el.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/el.png -------------------------------------------------------------------------------- /databasic/static/img/logos/northeastern.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/northeastern.png -------------------------------------------------------------------------------- /databasic/static/img/logos/samediff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/samediff.png -------------------------------------------------------------------------------- /databasic/static/img/logos/samediff_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/samediff_white.png -------------------------------------------------------------------------------- /databasic/static/img/logos/sd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/sd.png -------------------------------------------------------------------------------- /databasic/static/img/logos/sd@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/sd@2x.png -------------------------------------------------------------------------------- /databasic/static/img/logos/wc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/wc.png -------------------------------------------------------------------------------- /databasic/static/img/logos/wc@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/wc@2x.png -------------------------------------------------------------------------------- /databasic/static/img/logos/wordcounter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/wordcounter.png -------------------------------------------------------------------------------- /databasic/static/img/logos/wordcounter_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/wordcounter_white.png -------------------------------------------------------------------------------- /databasic/static/img/logos/wtf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/wtf.png -------------------------------------------------------------------------------- /databasic/static/img/logos/wtf@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/wtf@2x.png -------------------------------------------------------------------------------- /databasic/static/img/logos/wtfcsv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/wtfcsv.png -------------------------------------------------------------------------------- /databasic/static/img/logos/wtfcsv_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/logos/wtfcsv_white.png -------------------------------------------------------------------------------- /databasic/static/img/photos/home1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/photos/home1.png -------------------------------------------------------------------------------- /databasic/static/img/photos/home2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/photos/home2.png -------------------------------------------------------------------------------- /databasic/static/img/photos/home3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/photos/home3.png -------------------------------------------------------------------------------- /databasic/static/img/photos/home4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/photos/home4.png -------------------------------------------------------------------------------- /databasic/static/img/photos/home5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/photos/home5.png -------------------------------------------------------------------------------- /databasic/static/img/photos/home6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/photos/home6.png -------------------------------------------------------------------------------- /databasic/static/img/samediff-sheet-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/samediff-sheet-thumbnail.jpg -------------------------------------------------------------------------------- /databasic/static/img/wordcounter-sheet-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/wordcounter-sheet-thumbnail.jpg -------------------------------------------------------------------------------- /databasic/static/img/wtfcsv-sheet-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/static/img/wtfcsv-sheet-thumbnail.jpg -------------------------------------------------------------------------------- /databasic/static/js/connectthedots-validate.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function(){ 2 | var maxFileSize; 3 | 4 | if (typeof $('#max-file-size-in-mb').data() !== 'undefined') { 5 | maxFileSize = $('#max-file-size-in-mb').data().value; 6 | } 7 | 8 | jQuery.validator.addMethod("filesize", function(value, element, filesize) { 9 | return this.optional(element) || (element.files[0].size / 1048576 <= filesize); 10 | }); 11 | 12 | $(".paste").validate({ 13 | rules: { 14 | area: { 15 | required: true 16 | } 17 | }, 18 | messages: { 19 | area: { 20 | required: _("This field is required") 21 | } 22 | } 23 | }); 24 | 25 | $(".upload").validate({ 26 | rules: { 27 | upload: { 28 | required: true, 29 | extension: "csv|xlsx|xls", 30 | filesize: maxFileSize 31 | }, 32 | }, 33 | messages: { 34 | upload: { 35 | required: _("This field is required"), 36 | extension: _("Only these file types are accepted: csv, xls, xlsx"), 37 | filesize: _("Only files under " + maxFileSize + "MB are accepted") 38 | } 39 | } 40 | }); 41 | }); -------------------------------------------------------------------------------- /databasic/static/js/lib/jquery.flip.min.js: -------------------------------------------------------------------------------- 1 | /*! flip - v1.1.2 - 2016-10-20 2 | * https://github.com/nnattawat/flip 3 | * Copyright (c) 2016 Nattawat Nonsung; Licensed MIT */ 4 | 5 | !function(a){var b=function(){var a,b=document.createElement("fakeelement"),c={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(a in c)if(void 0!==b.style[a])return c[a]},c=function(b,c,d){this.setting={axis:"y",reverse:!1,trigger:"click",speed:500,forceHeight:!1,forceWidth:!1,autoSize:!0,front:".front",back:".back"},this.setting=a.extend(this.setting,c),"string"!=typeof c.axis||"x"!==c.axis.toLowerCase()&&"y"!==c.axis.toLowerCase()||(this.setting.axis=c.axis.toLowerCase()),"boolean"==typeof c.reverse&&(this.setting.reverse=c.reverse),"string"==typeof c.trigger&&(this.setting.trigger=c.trigger.toLowerCase());var e=parseInt(c.speed);isNaN(e)||(this.setting.speed=e),"boolean"==typeof c.forceHeight&&(this.setting.forceHeight=c.forceHeight),"boolean"==typeof c.forceWidth&&(this.setting.forceWidth=c.forceWidth),"boolean"==typeof c.autoSize&&(this.setting.autoSize=c.autoSize),("string"==typeof c.front||c.front instanceof a)&&(this.setting.front=c.front),("string"==typeof c.back||c.back instanceof a)&&(this.setting.back=c.back),this.element=b,this.frontElement=this.getFrontElement(),this.backElement=this.getBackElement(),this.isFlipped=!1,this.init(d)};a.extend(c.prototype,{flipDone:function(a){var c=this;c.element.one(b(),function(){c.element.trigger("flip:done"),"function"==typeof a&&a.call(c.element)})},flip:function(a){if(!this.isFlipped){this.isFlipped=!0;var b="rotate"+this.setting.axis;this.frontElement.css({transform:b+(this.setting.reverse?"(-180deg)":"(180deg)"),"z-index":"0"}),this.backElement.css({transform:b+"(0deg)","z-index":"1"}),this.flipDone(a)}},unflip:function(a){if(this.isFlipped){this.isFlipped=!1;var b="rotate"+this.setting.axis;this.frontElement.css({transform:b+"(0deg)","z-index":"1"}),this.backElement.css({transform:b+(this.setting.reverse?"(180deg)":"(-180deg)"),"z-index":"0"}),this.flipDone(a)}},getFrontElement:function(){return this.setting.front instanceof a?this.setting.front:this.element.find(this.setting.front)},getBackElement:function(){return this.setting.back instanceof a?this.setting.back:this.element.find(this.setting.back)},init:function(a){var b=this,c=b.frontElement.add(b.backElement),d="rotate"+b.setting.axis,e=2*b.element["outer"+("rotatex"===d?"Height":"Width")](),f={perspective:e,position:"relative"},g={transform:d+"("+(b.setting.reverse?"180deg":"-180deg")+")","z-index":"0",position:"relative"},h={"backface-visibility":"hidden","transform-style":"preserve-3d",position:"absolute","z-index":"1"};b.setting.forceHeight?c.outerHeight(b.element.height()):b.setting.autoSize&&(h.height="100%"),b.setting.forceWidth?c.outerWidth(b.element.width()):b.setting.autoSize&&(h.width="100%"),(window.chrome||window.Intl&&Intl.v8BreakIterator)&&"CSS"in window&&(f["-webkit-transform-style"]="preserve-3d"),c.css(h).find("*").css({"backface-visibility":"hidden"}),b.element.css(f),b.backElement.css(g),setTimeout(function(){var d=b.setting.speed/1e3||.5;c.css({transition:"all "+d+"s ease-out"}),"function"==typeof a&&a.call(b.element)},20),b.attachEvents()},clickHandler:function(b){b||(b=window.event),this.element.find(a(b.target).closest('button, a, input[type="submit"]')).length||(this.isFlipped?this.unflip():this.flip())},hoverHandler:function(){var b=this;b.element.off("mouseleave.flip"),b.flip(),setTimeout(function(){b.element.on("mouseleave.flip",a.proxy(b.unflip,b)),b.element.is(":hover")||b.unflip()},b.setting.speed+150)},attachEvents:function(){var b=this;"click"===b.setting.trigger?b.element.on(a.fn.tap?"tap.flip":"click.flip",a.proxy(b.clickHandler,b)):"hover"===b.setting.trigger&&(b.element.on("mouseenter.flip",a.proxy(b.hoverHandler,b)),b.element.on("mouseleave.flip",a.proxy(b.unflip,b)))},flipChanged:function(a){this.element.trigger("flip:change"),"function"==typeof a&&a.call(this.element)},changeSettings:function(a,b){var c=this,d=!1;if(void 0!==a.axis&&c.setting.axis!==a.axis.toLowerCase()&&(c.setting.axis=a.axis.toLowerCase(),d=!0),void 0!==a.reverse&&c.setting.reverse!==a.reverse&&(c.setting.reverse=a.reverse,d=!0),d){var e=c.frontElement.add(c.backElement),f=e.css(["transition-property","transition-timing-function","transition-duration","transition-delay"]);e.css({transition:"none"});var g="rotate"+c.setting.axis;c.isFlipped?c.frontElement.css({transform:g+(c.setting.reverse?"(-180deg)":"(180deg)"),"z-index":"0"}):c.backElement.css({transform:g+(c.setting.reverse?"(180deg)":"(-180deg)"),"z-index":"0"}),setTimeout(function(){e.css(f),c.flipChanged(b)},0)}else c.flipChanged(b)}}),a.fn.flip=function(b,d){return"function"==typeof b&&(d=b),"string"==typeof b||"boolean"==typeof b?this.each(function(){var c=a(this).data("flip-model");"toggle"===b&&(b=!c.isFlipped),b?c.flip(d):c.unflip(d)}):this.each(function(){if(a(this).data("flip-model")){var e=a(this).data("flip-model");!b||void 0===b.axis&&void 0===b.reverse||e.changeSettings(b,d)}else a(this).data("flip-model",new c(a(this),b||{},d))}),this}}(jQuery); 6 | //# sourceMappingURL=jquery.flip.min.js.map 7 | -------------------------------------------------------------------------------- /databasic/static/js/samediff-validate.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function(){ 3 | 4 | var maxFileSize; 5 | 6 | if( typeof $('#max-file-size-in-mb').data() !== 'undefined' ) { 7 | maxFileSize = $('#max-file-size-in-mb').data().value; 8 | } 9 | 10 | jQuery.validator.addMethod("custom_url", function(value, element) { 11 | return this.optional (element) || /^[^ "]+$/.test(value); 12 | }, _("You must input a valid url")); 13 | 14 | jQuery.validator.addClassRules({ 15 | custom_url: { custom_url: true } 16 | }); 17 | 18 | jQuery.validator.addMethod("multiple_files", function(value, element) { 19 | return this.optional (element) || $("input:file")[0].files.length == 2; 20 | }, _("You must select two files")); 21 | 22 | jQuery.validator.addMethod("filesize", function(value, element, filesize) { 23 | return this.optional (element) || (element.files[0].size / 1048576 <= filesize); 24 | }); 25 | 26 | jQuery.validator.addClassRules({ 27 | multiple_files: { multiple_files: true } 28 | }); 29 | 30 | $(".sample").validate({ 31 | rules: { 32 | sample: { 33 | required: true 34 | }, 35 | sample2: { 36 | required: true 37 | }, 38 | email: { 39 | required: true, 40 | email: true 41 | } 42 | }, 43 | messages: { 44 | sample: { 45 | required: _("This field is required") 46 | }, 47 | sample2: { 48 | required: _("This field is required") 49 | }, 50 | email: { 51 | required: _("This field is required"), 52 | email: _("Please enter a valid email address") 53 | } 54 | } 55 | }) 56 | $(".upload").validate({ 57 | rules: { 58 | upload: { 59 | required: true, 60 | extension: "txt|docx|rtf", 61 | filesize: maxFileSize 62 | }, 63 | upload2: { 64 | required: true, 65 | extension: "txt|docx|rtf", 66 | filesize: maxFileSize 67 | }, 68 | email: { 69 | required: true, 70 | email: true 71 | } 72 | }, 73 | messages: { 74 | upload: { 75 | required: _("This field is required"), 76 | extension: _("Only these file types are accepted: txt, docx, rtf"), 77 | filesize: _("Only files under " + maxFileSize + "MB are accepted") 78 | }, 79 | upload2: { 80 | required: _("This field is required"), 81 | extension: _("Only these file types are accepted: txt, docx, rtf"), 82 | filesize: _("Only files under " + maxFileSize + "MB are accepted") 83 | }, 84 | email: { 85 | required: _("This field is required"), 86 | email: _("Please enter a valid email address") 87 | } 88 | } 89 | }); 90 | }); -------------------------------------------------------------------------------- /databasic/static/js/samediff.js: -------------------------------------------------------------------------------- 1 | function renderSimilarityChart(elementSelector, dataset){ 2 | 3 | console.log("renderSimilarityChart to "+elementSelector); 4 | 5 | var width = 520, 6 | height = 280, 7 | formatPercent = d3.format(".0%"), 8 | formatNumber = d3.format(".0f"); 9 | 10 | var threshold = d3.scale.threshold() 11 | .domain([.5, 0.7, 0.8, 0.9]) 12 | .range( ["#e66101", "#fdb863", "#999999", "#b2abd2", "#5e3c99"] ); 13 | 14 | // A position encoding for the key only. 15 | var chartWidth = 450; 16 | 17 | var x = d3.scale.linear() 18 | .domain([0, 1]) 19 | .range([0, chartWidth]); // the width of the chart 20 | 21 | var xAxis = d3.svg.axis() 22 | .scale(x) 23 | .orient("bottom") 24 | .tickSize(13) 25 | .tickValues(threshold.domain()) 26 | .tickFormat(function(d) { return d; }); 27 | 28 | var svg = d3.select(elementSelector).append("svg") 29 | .attr("width", width) 30 | .attr("height", height); 31 | 32 | var g = svg.append("g") 33 | .attr("class", "key") 34 | .attr("transform", "translate(" + (width - chartWidth) / 2 + "," + 50 + ")"); 35 | 36 | g.selectAll("rect") 37 | .data(threshold.range().map(function(color) { 38 | var d = threshold.invertExtent(color); 39 | if (d[0] == null) d[0] = x.domain()[0]; 40 | if (d[1] == null) d[1] = x.domain()[1]; 41 | return d; 42 | })) 43 | .enter().append("rect") 44 | .attr("height", 10) 45 | .attr("x", function(d) { return x(d[0]); }) 46 | .attr("width", function(d) { return x(d[1]) - x(d[0]); }) 47 | .style("fill", function(d) { return threshold(d[0]); }); 48 | 49 | g.call(xAxis); 50 | 51 | g.append("text") 52 | .attr("class", "caption") 53 | .attr("y", -6) 54 | .text("Totally different"); 55 | g.append("text") 56 | .attr("class", "caption") 57 | .attr("y", -6) 58 | .attr("x", x.range()[1]) 59 | .text("Totally the same") 60 | .style("text-anchor", "end"); 61 | 62 | var g2 = svg.append("g") 63 | .attr("class", "key") 64 | .attr("transform", "translate(40,100)"); 65 | var yOffset = 0; 66 | var xOffset = 0; 67 | for(r=0;r0){ 86 | g2.append("line") 87 | .style("stroke",scoreColor) 88 | .attr("x1",x(score)-20) 89 | .attr("y1",-40) 90 | .attr("x2",x(score)-20) 91 | .attr("y2",yOffset-25); 92 | g2.append("line") 93 | .style("stroke",scoreColor) 94 | .attr("x1",xOffset+maxTxtWidth+10) 95 | .attr("y1",yOffset-25) 96 | .attr("x2",x(score)-20) 97 | .attr("y2",yOffset-25); 98 | yOffset += 10; 99 | } 100 | xOffset += 40; 101 | } 102 | } 103 | 104 | diffWordCloudDestination = null; 105 | 106 | function renderDiffWordCloud(elementSelector, dataset){ 107 | var maxScore = Math.max.apply(Math,dataset.map(function(o){return o.score;})) 108 | var fontSizeScale = d3.scale.linear() 109 | .domain([0, maxScore]) 110 | .range([0, 40]); 111 | console.log("renderDiffChart to "+elementSelector); 112 | diffWordCloudDestination = elementSelector; 113 | var layout = d3.layout.cloud() 114 | .size([420, 250]) 115 | .words(dataset) 116 | .padding(5) 117 | .rotate(0) 118 | .fontSize(function(d) { return fontSizeScale(d.score); }) 119 | .on("end", drawDiffWordCloud); 120 | layout.start(); 121 | } 122 | 123 | function drawDiffWordCloud(words) { 124 | console.log("drawDiffWordCloud to "+diffWordCloudDestination); 125 | var chartWidth = 520; 126 | d3.select(diffWordCloudDestination).append("svg") 127 | .attr("width", chartWidth) 128 | .attr("height", 260) 129 | .append("g") 130 | .attr("transform", "translate(" + chartWidth/2 + "," + 125 + ")") 131 | .selectAll("text") 132 | .data(words) 133 | .enter().append("text") 134 | .style("font-size", function(d) { return d.size + "px"; }) 135 | .attr("text-anchor", "middle") 136 | .attr("transform", function(d) { 137 | return "translate(" + [d.x, d.y] + ")rotate(" + d.rotate + ")"; 138 | }) 139 | .text(function(d) { return d.text; }); 140 | } 141 | -------------------------------------------------------------------------------- /databasic/static/js/tool.js: -------------------------------------------------------------------------------- 1 | 2 | var send_submit_event = function(toolName, source) { 3 | var submit = $.urlParam('submit'); 4 | if (submit) { 5 | ga('send', 'event', toolName, source, 'input-tab'); 6 | history.pushState('', window.title, window.location.href.replace('?submit=true', '')); 7 | } 8 | } 9 | 10 | $.urlParam = function(name){ 11 | var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href); 12 | if (results==null){ 13 | return null; 14 | } 15 | else{ 16 | return results[1] || 0; 17 | } 18 | } 19 | 20 | $(document).ready(function() { 21 | 22 | // Add classes for styling checkboxes 23 | $("input[type='checkbox']").change(function(){ 24 | if($(this).is(":checked")){ 25 | $(this).parent().parent().addClass("checked-div"); 26 | }else{ 27 | $(this).parent().parent().removeClass("checked-div"); 28 | } 29 | }); 30 | 31 | // Focus the first field when a tab is selected 32 | $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) { 33 | var tabId = $(this).attr('id').replace('tab-', ''); 34 | if (!$('body').hasClass('connectthedots')) { // don't autofocus on ConnectTheDots 35 | $('.tab-content') 36 | .find('#' + tabId) 37 | .find('.form-group:nth(1)') 38 | .find('.form-control:nth(0)')[0].focus (); 39 | } 40 | }); 41 | 42 | // Remember last pressed tab when navigating site 43 | var hash = window.location.hash; 44 | hash && $('ul.nav a[href="' + hash + '"]').tab('show'); 45 | 46 | $('.nav-tabs a').click(function (e) { 47 | $(this).tab('show'); 48 | history.pushState(null,null,this.hash); // use history so it doesn't refresh the page and navigate to element 49 | }); 50 | 51 | // Modals accessibility 52 | $('#video-modal').on('shown.bs.modal', function () { 53 | $('a').find('iframe').focus(); 54 | $('#video-modal-btn').prop('aria-expanded', true); 55 | }); 56 | 57 | $('#video-modal').on('hidden.bs.modal', function () { 58 | $('a').find('iframe').focus(); 59 | $('#video-modal-btn').prop('aria-expanded', false); 60 | }); 61 | 62 | $('#share-modal').on('shown.bs.modal', function () { 63 | $(this).find('input').focus(); 64 | $('#share-modal-btn').prop('aria-expanded', true); 65 | }); 66 | 67 | $('#share-modal').on('hidden.bs.modal', function () { 68 | $(this).find('input').focus(); 69 | $('#share-modal-btn').prop('aria-expanded', false); 70 | }); 71 | 72 | // Stop video when modal is closed 73 | $('.modal').each(function(){ 74 | var src = $(this).find('iframe').attr('src'); 75 | 76 | $(this).on('click', function(){ 77 | 78 | $(this).find('iframe').attr('src', ''); 79 | $(this).find('iframe').attr('src', src); 80 | 81 | }); 82 | }); 83 | 84 | handle_upload('upload'); 85 | handle_upload('upload2'); 86 | 87 | function handle_upload(id) { 88 | $('#browse-click-' + id).on('click', function () { 89 | $('.form-control[name="' + id + '"]').click(); 90 | setInterval(function() { 91 | var label = $('.form-control[name="' + id + '"]').val().replace("C:\\fakepath\\",""); 92 | if (label != "") { 93 | $('#browse-click-' + id).html(label); 94 | } 95 | }, 10); 96 | return false; 97 | }); 98 | } 99 | }); 100 | 101 | var trackOutboundLink = function(toolName, url, category) { 102 | ga('send', 'event', toolName, url, category, { 103 | 'transport': 'beacon', 104 | 'hitCallback': function(){document.location = url;} 105 | }); 106 | } 107 | -------------------------------------------------------------------------------- /databasic/static/js/wordcounter-validate.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function(){ 3 | 4 | var maxFileSize; 5 | 6 | if( typeof $('#max-file-size-in-mb').data() !== 'undefined' ) { 7 | maxFileSize = $('#max-file-size-in-mb').data().value; 8 | } 9 | 10 | jQuery.validator.addMethod("custom_url", function(value, element) { 11 | return this.optional (element) || /^[^ "]+$/.test(value); 12 | }, _("You must input a valid url")); 13 | 14 | jQuery.validator.addMethod("filesize", function(value, element, filesize) { 15 | return this.optional (element) || (element.files[0].size / 1048576 <= filesize); 16 | }); 17 | 18 | jQuery.validator.addClassRules({ 19 | custom_url: { custom_url: true } 20 | }); 21 | 22 | $(".paste").validate({ 23 | rules: { 24 | area: { 25 | required: true 26 | } 27 | }, 28 | messages: { 29 | area: { 30 | required: _("This field is required") 31 | } 32 | } 33 | }); 34 | $(".upload").validate({ 35 | rules: { 36 | upload: { 37 | required: true, 38 | extension: "txt|docx|rtf", 39 | filesize: maxFileSize 40 | } 41 | }, 42 | messages: { 43 | upload: { 44 | required: _("This field is required"), 45 | extension: _("Only these file types are accepted: txt, docx, rtf"), 46 | filesize: _("Only files under " + maxFileSize + "MB are accepted") 47 | } 48 | } 49 | }); 50 | $(".link").validate({ 51 | rules: { 52 | link: { 53 | required: true, 54 | custom_url: true, 55 | filesize: maxFileSize 56 | } 57 | }, 58 | messages: { 59 | link: { 60 | required: _("This field is required"), 61 | custom_url: _("You must input a URL"), 62 | filesize: _("Only files under " + maxFileSize + "MB are accepted") 63 | } 64 | } 65 | }); 66 | }); -------------------------------------------------------------------------------- /databasic/static/js/wtfcsv-validate.js: -------------------------------------------------------------------------------- 1 | 2 | $(document).ready(function(){ 3 | 4 | var maxFileSize; 5 | 6 | if( typeof $('#max-file-size-in-mb').data() !== 'undefined' ) { 7 | maxFileSize = $('#max-file-size-in-mb').data().value; 8 | } 9 | 10 | jQuery.validator.addMethod("spreadsheet", function(value, element) { 11 | return this.optional (element) || /^https:\/\/docs.google.com\/spreadsheets/.test(value); 12 | }, _("Link must be a valid Google Spreadsheet")); 13 | 14 | jQuery.validator.addMethod("filesize", function(value, element, filesize) { 15 | return this.optional (element) || (element.files[0].size / 1048576 <= filesize); 16 | }); 17 | 18 | jQuery.validator.addClassRules({ 19 | spreadsheet: { spreadsheet: true } 20 | }); 21 | 22 | $(".upload").validate({ 23 | rules: { 24 | upload: { 25 | required: true, 26 | extension: "csv|xlsx|xls", 27 | filesize: maxFileSize 28 | }, 29 | }, 30 | messages: { 31 | upload: { 32 | required: _("This field is required"), 33 | extension: _("Only these file types are accepted: csv, xls, xlsx"), 34 | filesize: _("Only files under " + maxFileSize + "MB are accepted") 35 | } 36 | } 37 | }); 38 | $(".link").validate({ 39 | rules: { 40 | link: { 41 | required: true, 42 | url: true, 43 | spreadsheet: true, 44 | filesize: maxFileSize 45 | } 46 | }, 47 | messages: { 48 | link: { 49 | required: _("This field is required"), 50 | url: _("You must input a URL"), 51 | filesize: _("Only files under " + maxFileSize + "MB are accepted") 52 | } 53 | } 54 | }); 55 | }); -------------------------------------------------------------------------------- /databasic/static/sass/_base.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | // Config 4 | @import "settings/fonts"; 5 | 6 | // Modules 7 | @import "modules/mixins"; 8 | 9 | // Layout 10 | @import "layout/header"; 11 | @import "layout/footer"; 12 | @import "layout/nav"; 13 | 14 | @mixin no-border() { 15 | -webkit-border-radius: 0px !important; 16 | -moz-border-radius: 0px !important; 17 | -o-border-radius: 0px !important; 18 | border-radius: 0px !important; 19 | border: 0px !important; 20 | } 21 | 22 | @mixin vertical-center() { 23 | position: relative; 24 | top: 50%; 25 | transform: perspective(1px) translateY(-50%); 26 | } 27 | 28 | .btn, 29 | th, td, 30 | .navbar-default, 31 | .form-control, 32 | .nav-tabs.nav-justified > li > a, 33 | .active a { 34 | @include no-border(); 35 | } 36 | 37 | html { 38 | position: relative; 39 | min-height: 100%; 40 | } 41 | 42 | body { 43 | margin: 0; 44 | color: $c-white; 45 | 46 | 47 | } 48 | 49 | .modal.fade .modal-dialog { 50 | -webkit-transition: -webkit-transform 0.1s ease-out; 51 | -moz-transition: -moz-transform 0.1s ease-out; 52 | -o-transition: -o-transform 0.1s ease-out; 53 | transition: transform 0.1s ease-out; 54 | } 55 | 56 | .centered-row { 57 | text-align: center; 58 | } 59 | 60 | .bottom-section { 61 | color: $c-theme-md; 62 | padding: 10px 0 20px 0; 63 | background-color: $c-white; 64 | @include selection($c-white, $c-theme-dk); 65 | 66 | h2 { 67 | text-align: center; 68 | } 69 | } 70 | 71 | a.invitation { 72 | display: block; 73 | color: $c-white !important; 74 | text-align: center; 75 | padding: 20px; 76 | margin-top: 15px; 77 | font-weight: bold; 78 | font-size: 24px; 79 | 80 | &.red { background-color: $c-pinkish-orange; } 81 | &.blue { background-color: $c-blue; } 82 | &.orange { background-color: #ff9800; } 83 | } -------------------------------------------------------------------------------- /databasic/static/sass/_results.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "base"; 4 | 5 | .no-results a { 6 | text-decoration: underline; 7 | } 8 | 9 | .no-results .tool-logo { 10 | margin-top: 20px; 11 | } 12 | 13 | .top-info { 14 | text-align: center; 15 | .summary { 16 | text-align: left; 17 | margin-bottom: 20px; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /databasic/static/sass/connectthedots.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "themes/blue-theme"; 4 | @import "tool"; 5 | @import "modules/input"; 6 | 7 | body { 8 | background-image: url("/static/img/backgrounds/tiled_background_blue.png"); 9 | 10 | } 11 | 12 | h4[role=alert] { 13 | margin-bottom: 40px; 14 | background-color:$c-red; 15 | color:$c-white; 16 | padding:20px; 17 | } 18 | 19 | .tool-logo { 20 | margin-bottom: 30px; 21 | } 22 | 23 | .inputs .form-group #area { 24 | height: 140px; 25 | resize: vertical; 26 | &.placeholder { 27 | color: $c-theme-lt; 28 | text-align: center; 29 | } 30 | } 31 | 32 | footer { 33 | nav { 34 | background-color: $c-theme-bg; 35 | } 36 | } -------------------------------------------------------------------------------- /databasic/static/sass/layout/_footer.scss: -------------------------------------------------------------------------------- 1 | body { 2 | margin-bottom: 40px !important; 3 | } 4 | 5 | footer { 6 | 7 | background-color: #666666; 8 | 9 | nav { 10 | .navbar-logo { 11 | padding: 12px; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /databasic/static/sass/layout/_header.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | header { 4 | background-color: $c-white; 5 | 6 | box-shadow: 0px 4px 0 0 rgba(0,0,0,0.3); 7 | 8 | #logo { 9 | vertical-align: bottom; 10 | img { 11 | max-height: 48px; 12 | } 13 | } 14 | 15 | #header-logo-container { 16 | text-align: center; 17 | .logo-container { 18 | height: 80px; 19 | img { 20 | position: absolute; 21 | bottom: 10px; 22 | } 23 | } 24 | } 25 | 26 | #language-selector { 27 | float: right; 28 | padding-top: 10px; 29 | padding-right: 10px; 30 | color: $c-black; 31 | font-family: HalisGR-Book; 32 | font-weight: normal; 33 | font-style: normal; 34 | 35 | a { 36 | color: white; 37 | &:after { 38 | content: ''; 39 | } 40 | } 41 | } 42 | #language-selector:hover{ 43 | background-color: white; 44 | } 45 | .badge:hover{ 46 | border-radius:10px !important; 47 | } 48 | .badge a:hover{ 49 | color:white; 50 | background:transparent; 51 | text-decoration:none; 52 | 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /databasic/static/sass/layout/_nav.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | nav { 4 | 5 | a { 6 | color: white; 7 | } 8 | 9 | background-color: #666666; 10 | 11 | .navbar-logo { 12 | padding: 12px; 13 | img { height: 26px; } 14 | } 15 | 16 | .navbar-toggle { 17 | .icon-bar { 18 | background-color: #ffffff; 19 | } 20 | } 21 | 22 | li { 23 | border-right: 1px solid #333333; 24 | } 25 | 26 | &.culture-navbar { 27 | background-color: $c-pinkish-orange !important; 28 | li { 29 | border-right: 1px solid #ffffff !important; 30 | } 31 | #language-selector { 32 | color: #ffffff; 33 | .badge { 34 | background-color: rgba(0,0,0,0.5); 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /databasic/static/sass/modules/_input.scss: -------------------------------------------------------------------------------- 1 | .inputs { 2 | 3 | input, select, textarea { 4 | color: $c-theme-dk; 5 | } 6 | 7 | @include selection($c-white, $c-theme-dk); 8 | 9 | input, textarea { 10 | @include placeholder { 11 | color: $c-theme-lt; 12 | text-align: center; 13 | } 14 | } 15 | 16 | input[id="email"], input[id="link"] { 17 | text-align: center; 18 | } 19 | 20 | .nav-tabs > li { 21 | font-size: 18px; 22 | } 23 | 24 | .checkbox, .radio { 25 | background-color: $c-unselected; 26 | margin: 0; 27 | font-size: 16px; 28 | 29 | &:hover { 30 | background-color: $c-hover; 31 | } 32 | 33 | > label { 34 | width: 100%; 35 | padding: 5px; 36 | text-transform: lowercase; 37 | 38 | label { padding: 5px; } 39 | } 40 | 41 | input[type="checkbox"] { 42 | position: relative; 43 | margin-left: 0; 44 | } 45 | } 46 | 47 | .checked-div { 48 | background-color: $c-selected; 49 | } 50 | 51 | .upload-field .btn { 52 | color: $c-theme-dk; 53 | background-color: $c-white; 54 | text-transform: lowercase; 55 | } 56 | 57 | input[id="upload"], input[id="upload2"] { 58 | position: absolute; 59 | left: 0; 60 | opacity: 0; 61 | z-index: -1; 62 | } 63 | 64 | .btn:focus, .btn:hover:active { 65 | background-color: $c-theme-md; 66 | color: $c-white; 67 | } 68 | } -------------------------------------------------------------------------------- /databasic/static/sass/modules/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow() { 2 | -webkit-box-shadow: 4px 4px 0 0 rgba(0, 0, 0, 0.2); 3 | -moz-box-shadow: 4px 4px 0 0 rgba(0, 0, 0, 0.2); 4 | box-shadow: 4px 4px 0 0 rgba(0, 0, 0, 0.2); 5 | } 6 | 7 | @mixin placeholder { 8 | &::-webkit-input-placeholder {@content} 9 | &:-moz-placeholder {@content} 10 | &::-moz-placeholder {@content} 11 | &:-ms-input-placeholder {@content} 12 | 13 | &:focus::-webkit-input-placeholder { color:transparent; } 14 | &:focus:-moz-placeholder { color:transparent; } /* FF 4-18 */ 15 | &:focus::-moz-placeholder { color:transparent; } /* FF 19+ */ 16 | &:focus:-ms-input-placeholder { color:transparent; } /* IE 10+ */ 17 | } 18 | 19 | @mixin selection($color, $highlight) { 20 | ::selection { 21 | color: $color; 22 | background: $highlight; 23 | } 24 | ::-moz-selection { 25 | color: $color; 26 | background: $highlight; 27 | } 28 | } 29 | 30 | @mixin tooltip($color) { 31 | &[role="definition"] { 32 | color: $color; 33 | &:hover, &:focus { 34 | text-decoration: underline; 35 | color: $color; 36 | } 37 | &:after { 38 | font-family: FontAwesome; 39 | vertical-align: super; 40 | font-size: 70%; 41 | padding-left: 2px; 42 | content: "\f059"; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /databasic/static/sass/samediff-results.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "themes/green-theme"; 4 | @import "tool"; 5 | @import "results"; 6 | @import "modules/input"; 7 | 8 | .table-info { 9 | min-height: 80px; 10 | } 11 | 12 | .column-info { 13 | background-color: $c-theme-md; 14 | color: $c-white; 15 | padding: 1px 20px 16px 20px; 16 | margin-top: 20px; 17 | } 18 | 19 | .chart-container { 20 | 21 | background-color: $c-theme-lt; 22 | 23 | .nav { 24 | margin-bottom: 1px !important; 25 | } 26 | 27 | .nav-tabs { 28 | @include no-border(); 29 | li { 30 | background-color: $c-theme-dk; 31 | a { 32 | @include no-border(); 33 | margin-right: 0; 34 | } 35 | } 36 | .active a { 37 | color: $c-white !important; 38 | background-color: $c-theme-lt !important; 39 | } 40 | } 41 | 42 | .navbar-right { 43 | margin-right: 0; 44 | } 45 | 46 | .content-top { 47 | background-color: $c-theme-dk; 48 | } 49 | 50 | table { 51 | border-spacing: 0; 52 | border-collapse: separate; 53 | padding: 8px 0; 54 | } 55 | 56 | .tab-pane { 57 | clear: both; 58 | background-color: $c-theme-lt; 59 | } 60 | } 61 | 62 | #title { 63 | margin: 30px 0; 64 | } 65 | 66 | 67 | .wordcloud-title { 68 | padding: 0; 69 | margin: 0; 70 | min-height: 70px; 71 | position: relative; 72 | border-bottom: 3px solid $c-white !important; 73 | 74 | h4 { 75 | position: absolute; 76 | bottom: 5px; 77 | } 78 | } 79 | 80 | .word { 81 | &:hover { 82 | cursor: pointer; 83 | fill: mix($c-yellow, $c-white, 50%); 84 | opacity: 1; 85 | } 86 | } 87 | 88 | 89 | /** d3 chart helpers **/ 90 | svg { 91 | font: 16px $font-lt; 92 | } 93 | 94 | .key { 95 | path { 96 | display: none; 97 | } 98 | 99 | line { 100 | stroke: #000; 101 | shape-rendering: crispEdges; 102 | } 103 | } 104 | 105 | .sameness-chart { 106 | background-color: rgb(238,238,238); 107 | } 108 | .diff-chart{ 109 | padding: 10px; 110 | background-color: rgb(238,238,238); 111 | } 112 | 113 | #logo { 114 | margin-top: -44px; 115 | } 116 | 117 | #title { 118 | margin-bottom: 0; 119 | } 120 | 121 | .tool-logo { 122 | padding: 0 5px; 123 | margin-bottom: 0; 124 | } 125 | 126 | footer { 127 | nav { 128 | background-color: $c-theme-bg; 129 | } 130 | } 131 | .expiring { 132 | color: #ff6633; 133 | background-color:white; 134 | padding:5px 10px; 135 | } 136 | #normalization-controls { 137 | h4 { 138 | display: inline-block; 139 | } 140 | .btn-toggle { 141 | margin-right: 5px; 142 | margin-left: 5px; 143 | .btn { 144 | border: 1px solid rgba(0, 0, 0, 0.2) !important; 145 | color: $c-white; 146 | } 147 | 148 | .btn-default { 149 | color: $c-white; 150 | font-weight: bold; 151 | background-color: $c-theme-bg; 152 | } 153 | 154 | .btn-primary:active, .btn-primary.active { 155 | background-color: #ff6633; //$c-theme-lt; 156 | } 157 | } 158 | } 159 | td{ 160 | padding:0 10px; 161 | } 162 | -------------------------------------------------------------------------------- /databasic/static/sass/samediff.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "themes/green-theme"; 4 | @import "tool"; 5 | @import "modules/input"; 6 | 7 | body { 8 | background-image: url("/static/img/backgrounds/tiled_background_green.png"); 9 | 10 | } 11 | 12 | #logo { 13 | margin-top: -44px; 14 | } 15 | 16 | .tool-logo { 17 | padding: 0 5px; 18 | margin-bottom: 0; 19 | } 20 | 21 | footer { 22 | nav { 23 | background-color: $c-theme-bg; 24 | } 25 | } -------------------------------------------------------------------------------- /databasic/static/sass/settings/_colors.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | $c-white: #fff; 4 | $c-grey: #eee; 5 | $c-darkgrey: #aaa; 6 | $c-black: #000; 7 | $c-red: #fd755a; 8 | $c-yellow: #fec52e; 9 | $c-green: #1ec293; 10 | $c-blue: #10b0f7; 11 | $c-pink: #ffacb8; 12 | 13 | $c-bright-sky-blue: #17bbff; 14 | $c-marigold: #ffc600; 15 | $c-pinkish-orange: #ff6643; 16 | $c-soft-pink: #ffadb9; 17 | $c-green-blue: #00cd94; 18 | $c-brownish-grey: #666666; 19 | $c-charcoal-grey: #4a4a4a; 20 | 21 | $c-theme-accent: $c-white !default; 22 | $c-theme-lt: $c-white !default; 23 | $c-theme-md: $c-white !default; 24 | $c-theme-dk: $c-black !default; 25 | $c-theme-bg: $c-black !default; 26 | 27 | $c-selected: $c-theme-accent !default; 28 | $c-unselected: $c-theme-md !default; 29 | $c-hover: $c-theme-dk !default; 30 | -------------------------------------------------------------------------------- /databasic/static/sass/settings/_fonts.scss: -------------------------------------------------------------------------------- 1 | $font-lt: HalisGR-Book; 2 | $font-md: HalisGR-Medium; 3 | $font-avenir: Avenir; 4 | $font-avenir-bold: AvenirBold; 5 | 6 | p, a, option, .btn, input, label { 7 | font-family: $font-lt; 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | h1, h2, h3, h4, th { 13 | font-family: $font-md; 14 | font-weight: normal; 15 | font-style: normal; 16 | 17 | a { 18 | font-family: $font-md; 19 | } 20 | } 21 | 22 | p { 23 | font-size: 18px; 24 | } 25 | 26 | a { 27 | color: $c-white; 28 | } 29 | 30 | @font-face { 31 | font-family: 'fontawesome-webfont'; 32 | src:url('/static/fonts/fontawesome-webfont.eot'); 33 | src:url('/static/fonts/fontawesome-webfont.eot') format('embedded-opentype'), 34 | url('/static/fonts/fontawesome-webfont.ttf') format('truetype'), 35 | url('/static/fonts/fontawesome-webfont.woff') format('woff'), 36 | url('/static/fonts/fontawesome-webfont.svg') format('svg'); 37 | font-weight: normal; 38 | font-style: normal; 39 | } 40 | 41 | @font-face { 42 | font-family: 'AvenirBold'; 43 | src:url('/static/fonts/avenir/AvenirNext-Bold.eot'); 44 | src:url('/static/fonts/avenir/AvenirNext-Bold.eot') format('embedded-opentype'), 45 | url('/static/fonts/avenir/AvenirNext-Bold.ttf') format('truetype'), 46 | url('/static/fonts/avenir/AvenirNext-Bold.woff') format('woff'), 47 | url('/static/fonts/avenir/AvenirNext-Bold.woff2') format('woff2'); 48 | font-weight: normal; 49 | font-style: normal; 50 | } 51 | 52 | 53 | .fa.noun_134105:before { 54 | font-family: 'fontawesome-webfont'; 55 | content: "\e900"; 56 | } -------------------------------------------------------------------------------- /databasic/static/sass/themes/blue-theme.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "settings/colors"; 4 | 5 | $c-theme-accent: #0098e6; 6 | $c-theme-lt: #41c0f9; 7 | $c-theme-md: #10b0f7; 8 | $c-theme-dk: #0076b3; 9 | $c-theme-bg: #10b0f7; 10 | 11 | $c-selected: $c-theme-lt; 12 | $c-unselected: $c-theme-md; 13 | $c-hover: $c-theme-dk; -------------------------------------------------------------------------------- /databasic/static/sass/themes/default-theme.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "settings/colors"; 4 | 5 | $c-theme-accent: $c-white; 6 | $c-theme-lt: $c-white; 7 | $c-theme-md: $c-white; 8 | $c-theme-dk: $c-black; 9 | 10 | $c-selected: $c-theme-accent; 11 | $c-unselected: $c-theme-md; 12 | $c-hover: $c-theme-dk; -------------------------------------------------------------------------------- /databasic/static/sass/themes/green-theme.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "settings/colors"; 4 | 5 | $c-theme-accent: #35e4b5; 6 | $c-theme-lt: #2cd5a7; 7 | $c-theme-md: #1ec293; 8 | $c-theme-dk: #1cb88c; 9 | $c-theme-bg: #20c898; 10 | 11 | $c-selected: $c-theme-accent; 12 | $c-unselected: $c-theme-md; 13 | $c-hover: $c-theme-dk; -------------------------------------------------------------------------------- /databasic/static/sass/themes/home-theme.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "settings/colors"; 4 | 5 | $c-theme-accent: #eee; 6 | $c-theme-lt: #ccc; 7 | $c-theme-md: #999; 8 | $c-theme-dk: #666; 9 | 10 | $c-selected: $c-theme-accent; 11 | $c-unselected: $c-theme-md; 12 | $c-hover: $c-theme-dk; -------------------------------------------------------------------------------- /databasic/static/sass/themes/red-theme.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "settings/colors"; 4 | 5 | $c-theme-accent: #fd8f79; 6 | $c-theme-lt: #fd755a; 7 | $c-theme-md: #fd755a; 8 | $c-theme-dk: #fc5739; 9 | $c-theme-bg: #fc674a; 10 | 11 | $c-selected: $c-theme-accent; 12 | $c-unselected: $c-theme-md; 13 | $c-hover: $c-theme-dk; -------------------------------------------------------------------------------- /databasic/static/sass/themes/yellow-theme.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "settings/colors"; 4 | 5 | $c-theme-accent: #FFB74C; 6 | $c-theme-lt: #ff9800; 7 | $c-theme-md: #ff9800; 8 | $c-theme-dk: #ff9800; 9 | $c-theme-bg: #ff9800; 10 | 11 | $c-selected: $c-theme-accent; 12 | $c-unselected: $c-theme-md; 13 | $c-hover: $c-theme-dk; -------------------------------------------------------------------------------- /databasic/static/sass/wordcounter-results.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "themes/red-theme"; 4 | @import "tool"; 5 | @import "results"; 6 | @import "modules/input"; 7 | 8 | body { 9 | background-color: $c-theme-md; 10 | } 11 | 12 | .tool-logo { 13 | margin: 40px 0 20px; 14 | } 15 | 16 | .word-cloud { 17 | min-height: 400px; 18 | text-align: center; 19 | } 20 | 21 | #frequencies { 22 | background-color: $c-theme-dk; 23 | 24 | h2 { 25 | text-align: center; 26 | text-transform: uppercase; 27 | padding: 20px 0; 28 | 29 | .glyphicon { 30 | color: $c-white; 31 | font-size: 32px; 32 | top: 7px; 33 | opacity: 0.6; 34 | 35 | &:hover { 36 | color: $c-white; 37 | opacity: 0.8; 38 | } 39 | 40 | &:focus { 41 | color: $c-white; 42 | opacity: 0.8; 43 | } 44 | 45 | &:active { 46 | color: $c-white; 47 | opacity: 0.8; 48 | } 49 | } 50 | } 51 | 52 | table { 53 | 54 | $scaled-row-count: 10; 55 | $min-font-size: 18px; 56 | $max-font-size: 6px; // min size + max size = largest font 57 | @for $i from 0 through $scaled-row-count { 58 | tr:nth-child(#{abs($i - $scaled-row-count)}) { 59 | font-size: $min-font-size + $max-font-size * $i / $scaled-row-count; 60 | } 61 | } 62 | } 63 | } 64 | 65 | svg { 66 | g .cloud-text { 67 | fill: $c-white; 68 | font-family: $font-lt; 69 | } 70 | } 71 | 72 | footer { 73 | nav { 74 | background-color: $c-theme-bg; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /databasic/static/sass/wordcounter.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "themes/red-theme"; 4 | @import "tool"; 5 | @import "modules/input"; 6 | 7 | body { 8 | background-image: url("/static/img/backgrounds/tiled_background_red.png"); 9 | 10 | } 11 | 12 | .tool-logo { 13 | margin-bottom: 10px; 14 | } 15 | 16 | footer { 17 | nav { 18 | background-color: $c-theme-bg; 19 | } 20 | } -------------------------------------------------------------------------------- /databasic/static/sass/wtfcsv-results.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "themes/yellow-theme"; 4 | @import "tool"; 5 | @import "results"; 6 | @import "modules/input"; 7 | 8 | .summary { 9 | color: $c-theme-dk; 10 | a { @include tooltip($c-white); } 11 | } 12 | 13 | body { 14 | background-color: $c-white; 15 | } 16 | 17 | #wtfcsv-results { 18 | margin-top:30px; 19 | } 20 | 21 | h3 a { 22 | color: $c-theme-md; 23 | &:hover, &:active { 24 | color: $c-theme-md; 25 | } 26 | } 27 | 28 | #intro { 29 | color: $c-white; 30 | .intro-container { 31 | margin-left: 10px; 32 | margin-right: 10px; 33 | background-color: $c-theme-md; 34 | padding: 15px 0; 35 | 36 | .tool-logo { 37 | margin: 15px 0; 38 | } 39 | 40 | h2 { 41 | color: $c-white !important; 42 | } 43 | 44 | h3 a { 45 | color: $c-white; 46 | } 47 | 48 | p { 49 | color: $c-white; 50 | } 51 | } 52 | } 53 | 54 | .column-info { 55 | .front, .back { 56 | .card-content { 57 | padding: 1px 20px 16px 20px; 58 | background-color: $c-theme-md; 59 | height: 100%; 60 | } 61 | } 62 | .front { 63 | color: $c-white; 64 | position: relative !important; 65 | 66 | > h3 > .glyphicon { 67 | font-size: smaller; 68 | } 69 | } 70 | .back { 71 | top: 0; 72 | } 73 | li { 74 | list-style: none; 75 | } 76 | } 77 | 78 | .ghost { 79 | > div .front, .back { 80 | border: 4px solid $c-red; 81 | } 82 | } 83 | 84 | .list-group-item { 85 | @include no-border(); 86 | padding: 10px; 87 | // h3 { cursor: move; } // uncomment if dragging enabled 88 | } 89 | 90 | ul.nav.nav-tabs { 91 | @media (max-width: 767px) { width: 100%; } 92 | @media (min-width: 768px) { width: 60%; } 93 | margin: 0 auto; 94 | font-size: 18px; 95 | 96 | li { 97 | a { 98 | color: $c-white; 99 | background-color: $c-unselected; 100 | } 101 | &.active a { 102 | background-color: $c-selected; 103 | } 104 | &:hover a { 105 | color: $c-white; 106 | background-color: $c-hover; 107 | } 108 | } 109 | } 110 | 111 | #what-next { 112 | margin-top: 20px; 113 | } 114 | 115 | .affix { 116 | top: 0px; 117 | z-index: 1; 118 | width: 100%; 119 | } 120 | 121 | .card { 122 | .card-top { 123 | height: 65px; 124 | 125 | .data-type { 126 | float: left; 127 | 128 | i { 129 | color: $c-red; 130 | border: 2px solid !important; 131 | border-radius: 20px !important; 132 | font-size: 14px; 133 | padding: 4px; 134 | } 135 | } 136 | 137 | .card-name { 138 | float: left; 139 | padding: 3px 2px 3px 12px; 140 | } 141 | 142 | .close-button { 143 | float: right; 144 | margin-top: 20px; 145 | h3 { 146 | color: $c-white; 147 | opacity: 0.75; 148 | 149 | &:hover { 150 | opacity: 1; 151 | cursor: pointer; 152 | } 153 | } 154 | } 155 | 156 | .flip-icon { 157 | i { 158 | color: $c-white; 159 | } 160 | } 161 | } 162 | 163 | .card-bottom { 164 | ul { 165 | padding-left: 0px; 166 | ul { 167 | padding-left: 10px; 168 | } 169 | } 170 | } 171 | 172 | .card-chart { 173 | } 174 | 175 | } 176 | 177 | .list-group { 178 | .hidden-card { 179 | display: none; 180 | } 181 | } 182 | 183 | .no-results { 184 | color: $c-theme-dk; 185 | a { 186 | color: $c-theme-dk; 187 | } 188 | } 189 | 190 | .d3-tip { 191 | font: $font-lt; 192 | background: $c-white; 193 | color: #C8523B; 194 | padding: 8px; 195 | font-weight: normal; 196 | border: 1px solid #C8523B !important; 197 | box-shadow: 1px 1px 1px 1px rgba(0,0,0,0.2); 198 | font-size: 13px; 199 | 200 | .tip-size { 201 | color: black; 202 | font-weight: bold; 203 | } 204 | } 205 | .d3-tip:after { 206 | color: $c-white; 207 | } 208 | 209 | footer { 210 | nav { 211 | background-color: $c-theme-bg; 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /databasic/static/sass/wtfcsv.scss: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | @import "themes/yellow-theme"; 4 | @import "tool"; 5 | @import "modules/input"; 6 | 7 | body { 8 | background-image: url("/static/img/backgrounds/tiled_background_yellow.png"); 9 | } 10 | 11 | footer { 12 | nav { 13 | background-color: $c-theme-bg; 14 | } 15 | } -------------------------------------------------------------------------------- /databasic/tasks.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | from databasic import app, mongo 4 | #from databasic import mail 5 | #from databasic.celeryapp import celery_app 6 | from flask.ext.mail import Message 7 | from databasic.logic import tfidfanalysis 8 | ''' 9 | @celery_app.task(serializer='json',bind=True) 10 | def save_tfidf_results(self, job_id): 11 | 12 | job_info = mongo.find_document('samediff', job_id) 13 | 14 | # tfidf them 15 | filepaths = job_info['filepaths'] 16 | tfidf = tfidfanalysis.tf_idf(filepaths) 17 | cosine_similarity = tfidfanalysis.cosine_similarity(filepaths) 18 | 19 | # save the results back to the db (based on the job_number) 20 | job_info['tfidf'] = tfidf 21 | job_info['cosineSimilarity'] = cosine_similarity 22 | 23 | # delete the raw input files 24 | if not job_info['is_sample_data']: 25 | with app.app_context(): 26 | for path in job_info['filepaths']: 27 | os.remove(path) 28 | del job_info['filepaths'] 29 | 30 | job_info['status'] = 'complete' 31 | mongo.save_job('samediff', job_info) 32 | # TODO: catch any exceptions and queue them up for retry attempts 33 | 34 | # notify them with email 35 | # TODO: Internationalize and put the text stuff into some kind of templating structure 36 | name = job_info['email'].split('@')[0] 37 | email_body = u'Dear %s, \n\nYour SameDiff job is ready at this URL: %s! \n\nSincerely, \n %s ' % (name, job_info['results_url'], settings.get('mail', 'from_email')) 38 | msg = Message(u'Your SameDiff job is ready!', 39 | recipients=[job_info['email']], 40 | body=email_body, 41 | sender=settings.get('mail', 'from_email')) 42 | with app.app_context(): 43 | mail.send(msg) 44 | 45 | print "sent ya an email ;)" 46 | ''' -------------------------------------------------------------------------------- /databasic/templates/_language_selector.html: -------------------------------------------------------------------------------- 1 |
2 | {{ _("Choose your language: ") }} 3 | 4 | {# NOTE FOR WELSH - Data Cymru displays only WELSH English and Welsh - en_CY and cy. #} 5 | {% if 'cymru' in request.host or 'localhost' in request.host %} 6 | 7 | en 8 | {% else %} 9 | en 10 | es 11 | pt 12 | da 13 | {% endif %} 14 | cy 15 |
16 | -------------------------------------------------------------------------------- /databasic/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {% block head %} 7 | 8 | 9 | 10 | {% block title %}{% endblock %} 11 | 12 | 13 | {% assets "css_base" %}{% endassets %} 14 | 15 | {% endblock %} 16 | {% block custom_css %}{% endblock %} 17 | 18 | 19 | 20 | {% block nav %}{% endblock %} 21 | {% block body %}{% endblock %} 22 | {% block footer %}{% endblock %} 23 | {% include 'scripts.html' %} 24 | {% block custom_scripts %}{% endblock %} 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /databasic/templates/connectthedots/connectthedots.html: -------------------------------------------------------------------------------- 1 | {% extends 'tool_base.html' %} 2 | {% from 'macros.html' import render_forms, hover_tooltip with context %} 3 | 4 | {% block title %}{{ _('ConnectTheDots') }}{% endblock %} 5 | 6 | {% block custom_css %} 7 | 8 | 9 | {% endblock %} 10 | 11 | {% block custom_scripts %} 12 | 13 | 14 | 47 | {% endblock %} 48 | 49 | {% block nav %} 50 | {% include 'tool_header.html' %} 51 | {% endblock %} 52 | 53 | {% block body %} 54 |
55 |
56 | 57 |
58 |
59 | {{ tool_logo() }} 60 | 63 |

{{ _('Analyzing the connections between the "dots" in your data is a fundamentally different approach to understanding it. This tool shows you a network diagram to reveal those links, and gives you a high level report about what your network looks like.') }}

64 |
65 |
66 |
67 | {% if input_error == 'paste' %} 68 | 69 | {% elif input_error == 'upload' %} 70 | 71 | {% endif %} 72 |
73 | {{ render_forms(forms, action_url=tool_name, action_text=_('Graph')) }} 74 |
75 | {{ about_section(_('ConnectTheDots'), '191074419', 76 | url_for('static', filename='img/ctd-sheet-thumbnail.png'), 77 | "/"+g['current_lang']+"/connectthedots/connect-the-dots-activity-guide.pdf" 78 | ) }} 79 |
80 | {% endblock %} -------------------------------------------------------------------------------- /databasic/templates/connectthedots/no_results.html: -------------------------------------------------------------------------------- 1 | {% extends "no_results.html" %} 2 | -------------------------------------------------------------------------------- /databasic/templates/culture/connections.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {% extends "culture_activity_base.html" %} 4 | 5 | {% block title %}{{ _("Build and Analyze a Network")}}{% endblock %} 6 | 7 | {% block culture_body %} 8 | 9 |
10 | 11 |
12 |
13 |
14 | 15 |
16 |
17 |

{{ _("Build and Analyze a Network")}}

18 |

{{ _("Learn how to ask different types of questions based on a network of data") }}

19 |
20 |
21 | 22 | {# Set Up #} 23 |
24 |
25 |

{{ _("Set Up") }}

26 |

{{ _("This activity will take 30 to 45 minutes. You should have these materials on hand:") }}

27 |
    28 |
  • {{ _("A basic Internet connection")}}
  • 29 |
  • {{ _("A phone, tablet, or computer for each small group of 3 people")}}
  • 30 |
  • {{ _("A projector connected to a computer")}}
  • 31 |
32 |

{{ _("Download and print the activity guide") }}

33 |
34 |
35 | 36 | {# Kick Off #} 37 |
38 |
1
39 |
40 |

{{ _("Kick-Off The Activity") }}

41 |

{{ _("Network graphs are very trendy right now, but few know how to read them, nor why they they might be useful. In this activity you'll create a dataset about local restaurants people recommend, build a network graph out of that data, and then think about questions you can ask it. You will use Databasic.io's Connect the Dots tool to do this.") }}

42 |

{{ _("Use Connect the Dots") }} 43 |

{{ _("Participants will understand and build familiarity with some standard terms and approaches to working with network graphs. Begin by sharing some inspirational examples, then fill in a spreadsheet together of restaurants and who recommends them. This should have two columns - 'Person' and 'Restaurant'. Then paste this data into Connect the Dots to analyze it. Share the URL and have people poke at it, or other sample data, to look for insights and prompt questions.") }}

44 |
45 |
46 | 47 |
48 |
49 | 50 | {# Share Back #} 51 |
52 |
2
53 |
54 |

{{ _("Have Everyone Share Back") }}

55 |

{{ _("After 10 minutes bring everyone back together to share any insights they found. Were there any obvious benefits they ran into by analyzing this data as a network (instead of a table)? Were there any questions that here harder to dig into? Were any of the algorithms mentioned useful?") }}

56 |
57 |
58 | 59 | {# Next Steps #} 60 |
61 |
3
62 |
63 |

{{ _("Wrap-Up and Talk Next Steps") }}

64 |

{{ _("Now that you've done some basic network graph analysis, help the participants think about any network data your organization has on hand. Are there any questions that came up, or ideas, about steps people should take with your in-house data?") }}

65 |
66 |
67 | 68 |
69 | 70 |
71 | 72 | {% endblock %} 73 | -------------------------------------------------------------------------------- /databasic/templates/culture/culture_activity_base.html: -------------------------------------------------------------------------------- 1 | {% extends "culture_base.html" %} 2 | 3 | {% block custom_scripts %} 4 | 12 | {% endblock %} 13 | -------------------------------------------------------------------------------- /databasic/templates/culture/culture_base.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% from "macros.html" import url_with_language %} 4 | 5 | {% block custom_css %} 6 | 7 | {% endblock %} 8 | 9 | {% block body %} 10 |
11 | 41 |
42 | {% block culture_body %}{% endblock %} 43 | {% endblock %} 44 | 45 | {% block footer %} 46 |
47 |
48 |
49 |
50 |
51 | DataBasic 52 |
53 |
54 | Engagement Lab at Emerson College 55 |
56 |
57 | Northeastern School of Journalism and Media Innovation 58 |
59 |
60 | Dept of Urban Studies and Planning at MIT 61 |
62 |
63 |
64 |
65 |
66 | {% endblock %} 67 | -------------------------------------------------------------------------------- /databasic/templates/footer.html: -------------------------------------------------------------------------------- 1 | {% macro li_tool(link, name) -%} 2 |
  • 3 | 5 | {{ name }} 6 |
  • 7 | {%- endmacro %} 8 | 9 | {% macro footer_menu() -%} 10 | 40 | {%- endmacro %} 41 | -------------------------------------------------------------------------------- /databasic/templates/header_base.html: -------------------------------------------------------------------------------- 1 | {% from "macros.html" import url_with_language %} 2 |
    3 |
    4 | {% include '_language_selector.html' %} 5 |
    6 | 7 |
    8 |
    9 | {% block header_content %}{% endblock %} 10 |
    11 |
    12 |
    13 | -------------------------------------------------------------------------------- /databasic/templates/home_header.html: -------------------------------------------------------------------------------- 1 | {% extends "header_base.html" %} 2 | 3 | {% block header_content %} 4 |
    5 | 6 |
    7 |
    8 | 12 |
    13 |
    14 | 15 |
    16 | {% endblock %} -------------------------------------------------------------------------------- /databasic/templates/no_results.html: -------------------------------------------------------------------------------- 1 | {% extends "tool_base.html" %} 2 | 3 | {% block title %}{{ _('No results') }}{% endblock %} 4 | 5 | {% block custom_css %} 6 | 7 | {% endblock %} 8 | 9 | {% block nav %} 10 | {% include 'tool_header.html' %} 11 | {% endblock %} 12 | 13 | {% block body %} 14 |
    15 |
    16 |
    17 |
    18 | {{ tool_logo() }} 19 | 20 |

    {{ _('They might have expired. Why not try analyzing some new data?', lang=g['current_lang'], tool_name=tool_name) }}

    21 |
    22 |
    23 |
    24 |
    25 | {% endblock %} -------------------------------------------------------------------------------- /databasic/templates/samediff/no_results.html: -------------------------------------------------------------------------------- 1 | {% extends "no_results.html" %} 2 | -------------------------------------------------------------------------------- /databasic/templates/samediff/samediff.html: -------------------------------------------------------------------------------- 1 | {% extends "tool_base.html" %} 2 | {% from 'macros.html' import render_forms, hover_tooltip with context %} 3 | 4 | {% block title %}{{ _('SameDiff') }}{% endblock %} 5 | 6 | {% block custom_css %} 7 | 8 | 9 | {% endblock %} 10 | 11 | {% block nav %} 12 | {% include 'tool_header.html' %} 13 | {% endblock %} 14 | 15 | {% block body %} 16 |
    17 |
    18 |
    19 |
    20 | {{ tool_logo() }} 21 | 22 |

    {{ _('SameDiff compares one %(corpus)s of text to another corpus of text to show you similarities and differences. It uses a %(cosine_similarity)s %(algorithm)s to rate whether the documents are really similar or totally different.', 23 | corpus=hover_tooltip(_('corpus'), 'corpus', _("A collection of written texts. For example, all of the lyrics in Katy Perry songs.") ), 24 | cosine_similarity=hover_tooltip(_('cosine similarity'), 'cosine similarity', _("The Cosine Similarity score tries to tell you how similar two documents are based on the number of times words are used in each.")), 25 | algorithm=hover_tooltip(_('algorithm'), 'algorithm', _("A set of steps you (or a computer) do in order to solve a problem. For example, when you type in a search term, Google runs an algorithm to figure out which pages to show you.") )) }}

    26 |
    27 |
    28 | {{ render_forms(forms, action_url=tool_name, action_text=_('Compare')) }} 29 |
    30 | {{ about_section(_('SameDiff'), '150671162', 31 | url_for('static', filename='img/samediff-sheet-thumbnail.jpg'), 32 | "/"+g['current_lang']+"/samediff/samediff-activity-guide.pdf" 33 | ) }} 34 |
    35 | {% endblock %} -------------------------------------------------------------------------------- /databasic/templates/scripts.html: -------------------------------------------------------------------------------- 1 | {% assets "js_base" %} 2 | 3 | {% endassets %} 4 | 5 | 8 | 9 | 28 | 29 | 34 | 43 | 44 | {% if 'cymru' in request.host or '127.0.0.1' in request.host %} 45 | 46 | 59 | 60 | {% endif %} 61 | -------------------------------------------------------------------------------- /databasic/templates/tool_base.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% from "footer.html" import footer_menu %} 3 | 4 | {% macro tool_logo() -%} 5 | 6 | {%- endmacro %} 7 | 8 | {% macro what_next(text, tools=[]) -%} 9 |
    10 |
    11 |
    12 |
    13 |

    {{ _('What do I do next?') }}

    14 |

    {{ text }}

    15 |

    {{ _("Try these other tools to do more full-fledged analysis:") }}

    16 |
    21 |
    22 |
    23 |
    24 | {%- endmacro %} 25 | 26 | {% macro about_section(name, video_id, activity_sheet_thumbnail_img, activity_sheet_en, activity_sheet_es) -%} 27 |
    28 |
    29 |
    30 |
    31 |

    {{ _("About %(tool_name)s", tool_name=name) }}

    32 | 35 |
    36 |
    37 |
    38 |

    {{ _("Are you an Educator? Try our Activity Guide") }}

    39 |
    40 |
    41 |
    42 |

    {{_("DataBasic activities are suitable for classes and workshops for participants from middle school through higher education. No prior data experience necessary!")}}

    43 |
    44 | 50 |
    51 |
    52 |
    53 |
    54 |
    55 | {%- endmacro %} 56 | 57 | {% block footer %} 58 |
    59 | {% block custom_footer %}{% endblock %} 60 | {{ footer_menu() }} 61 |
    62 | {% endblock %} 63 | 64 | {% block custom_scripts %} 65 | 66 | 67 | {% block results_scripts %}{% endblock %} 68 | {% endblock %} 69 | -------------------------------------------------------------------------------- /databasic/templates/tool_header.html: -------------------------------------------------------------------------------- 1 | {% extends "header_base.html" %} 2 | {% block header_content %} 3 |
    4 | 5 |
    6 | {% endblock %} -------------------------------------------------------------------------------- /databasic/templates/wordcounter/no_results.html: -------------------------------------------------------------------------------- 1 | {% extends "no_results.html" %} 2 | -------------------------------------------------------------------------------- /databasic/templates/wordcounter/run-activity.html: -------------------------------------------------------------------------------- 1 | {% extends "tool_base.html" %} 2 | 3 | {% block title %}{{ _('Run the Activity') }}{% endblock %} 4 | 5 | {% block custom_css %} 6 | 7 | {% endblock %} 8 | 9 | {% block nav %} 10 | {% include 'tool_header.html' %} 11 | {% endblock %} 12 | 13 | {% block body %} 14 |
    15 |
    16 |
    17 |
    18 | 19 |

    {{ _('Sketch a Story') }}

    20 |

    {{ _('Welcome to the WordCounter Sketch a Story activity! These videos will help you run the activity.')}}

    21 | 22 |

    {{ _('We\'re ready to start') }}

    23 | 24 | 25 |

    {{ _('Done with our stories! Time to share-back!') }}

    26 | 27 | 28 |

    {{ _('All done. What next?') }}

    29 | 30 | 31 |
    32 |
    33 |
    34 |
    35 | {% endblock %} 36 | -------------------------------------------------------------------------------- /databasic/templates/wordcounter/wordcounter.html: -------------------------------------------------------------------------------- 1 | {% extends "tool_base.html" %} 2 | {% from 'macros.html' import render_forms, about_section, hover_tooltip with context %} 3 | 4 | {% block title %}{{ _('WordCounter') }}{% endblock %} 5 | 6 | {% block custom_css %} 7 | 8 | 9 | 10 | {% endblock %} 11 | 12 | {% block nav %} 13 | {% include 'tool_header.html' %} 14 | {% endblock %} 15 | 16 | {% block body %} 17 |
    18 |
    19 |
    20 |
    21 | {{ tool_logo() }} 22 |

    {{ _('WordCounter analyzes your text and tells you the most common words and phrases.') }}

    23 | 24 | 25 |

    {{ _('This tool helps you count words, %(bigrams)s, and %(trigrams)s in plain text. This is often the first step in quantitative text analysis.', 26 | bigrams=hover_tooltip( _('bigrams'), 'bigrams', _('A bigram is a two word phrase') ), 27 | trigrams=hover_tooltip( _('trigrams'), 'trigrams', _('A trigram is a three word phrase') ) ) }}

    28 |
    29 |
    30 | {{ render_forms(forms, action_url=tool_name, action_text=_('Count')) }} 31 |
    32 | {{ about_section(_('WordCounter'), '150671183', 33 | url_for('static', filename='img/wordcounter-sheet-thumbnail.jpg'), 34 | "/"+g['current_lang']+"/wordcounter/wordcounter-activity-guide.pdf" 35 | ) }} 36 |
    37 | {% endblock %} 38 | -------------------------------------------------------------------------------- /databasic/templates/wtfcsv/no_results.html: -------------------------------------------------------------------------------- 1 | {% extends "no_results.html" %} 2 | -------------------------------------------------------------------------------- /databasic/templates/wtfcsv/wtfcsv.html: -------------------------------------------------------------------------------- 1 | {% extends "tool_base.html" %} 2 | {% from 'macros.html' import render_forms, hover_tooltip with context %} 3 | 4 | {% block title %}{{ _('WTFcsv') }}{% endblock %} 5 | 6 | {% block custom_css %} 7 | 8 | 9 | {% endblock %} 10 | 11 | {% block nav %} 12 | {% include 'tool_header.html' %} 13 | {% endblock %} 14 | 15 | {% block body %} 16 |
    17 |
    18 |
    19 |
    20 | {{ tool_logo() }} 21 |

    {{ _('WTFcsv tells you WTF is going on with your .csv file.') }}

    22 |

    {{ _('Data arrives at your doorstep in the form of a spreadsheet but how do you find a story in rows and columns? WTFcsv provides the first step by characterizing each column\'s %(data_type)s and contents so that you can ask more questions.', 23 | data_type=hover_tooltip( _('data type'), 'data type', _("Data is often classified by type. Common types of data include numbers, dates and text.") )) }}

    24 |
    25 |
    26 | {{ render_forms(forms, action_url=tool_name, action_text=_('Analyze')) }} 27 |
    28 | {{ about_section(_('WTFcsv'), '150216437', 29 | url_for('static', filename='img/wtfcsv-sheet-thumbnail.jpg'), 30 | "/"+g['current_lang']+"/wtfcsv/wtfcsv-activity-guide.pdf" 31 | ) }} 32 |
    33 | {% endblock %} -------------------------------------------------------------------------------- /databasic/translations/cy/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/translations/cy/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /databasic/translations/da/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/translations/da/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /databasic/translations/en_CY/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/translations/en_CY/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /databasic/translations/es/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/translations/es/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /databasic/translations/pt/LC_MESSAGES/messages.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/translations/pt/LC_MESSAGES/messages.mo -------------------------------------------------------------------------------- /databasic/views/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/databasic/views/__init__.py -------------------------------------------------------------------------------- /databasic/views/culture.py: -------------------------------------------------------------------------------- 1 | import logging 2 | import random 3 | from flask import Blueprint, render_template 4 | 5 | mod = Blueprint('culture', __name__, url_prefix='//culture', template_folder='../templates/culture') 6 | 7 | logger = logging.getLogger(__name__) 8 | 9 | 10 | @mod.route('/', methods=('GET', 'POST')) 11 | def index(): 12 | # TODO: move to .json file for easier maintenance 13 | quotes = [ 14 | { 15 | 'text': "The Data Culture Project allowed us to change a mindset about data", 16 | 'author': "Andrés Felipe Vera Ramírez, El Mundo/Radio Clarin" 17 | }, 18 | { 19 | 'text': "The DCP program helped us look at data in a different way", 20 | 'author': "Jennifer Connolly, Junior Achievement of Western Massachusetts" 21 | }, 22 | { 23 | 'text': "This program was accessible to people of all levels", 24 | 'author': "Jennifer Connolly, Junior Achievement of Western Massachusetts" 25 | }, 26 | { 27 | 'text': "The tools were accessible and the pacing of the workshops was great", 28 | 'author': "Michael Morisy, MuckRock" 29 | }, 30 | { 31 | 'text': "Folks who don’t typically use data in their day-to-day roles engaged in the sessions", 32 | 'author': "Michael Smith Foundation for Health Research" 33 | }, 34 | { 35 | 'text': "I saw a big change in how our partners treated data", 36 | 'author': "Erika Lapsys, Telluride Foundation" 37 | }, 38 | { 39 | 'text': "For the first time, the numbers [from our grantees] were consistent", 40 | 'author': "Erika Lapsys, Telluride Foundation" 41 | }, 42 | { 43 | 'text': "Participants started looking at ... which piece of data is more relevant for which type of stakeholder", 44 | 'author': "Maryna Taran, World Food Programme" 45 | } 46 | ] 47 | return render_template('culture.html', featured_quote=random.choice(quotes)) 48 | 49 | 50 | @mod.route('/sketch-a-story') 51 | def sketch(): 52 | return render_template('sketch.html') 53 | 54 | 55 | @mod.route('/convince-me') 56 | def convince(): 57 | return render_template('convince.html') 58 | 59 | 60 | @mod.route('/ask-questions') 61 | def questions(): 62 | return render_template('questions.html') 63 | 64 | 65 | @mod.route('/build-a-sculpture') 66 | def sculpture(): 67 | return render_template('sculpture.html') 68 | 69 | 70 | @mod.route('/deconstruct-a-dataviz') 71 | def deconstruct(): 72 | return render_template('deconstruct.html') 73 | 74 | 75 | @mod.route('/make-word-webs') 76 | def word_webs(): 77 | return render_template('word_webs.html') 78 | 79 | 80 | @mod.route('/connections') 81 | def connections(): 82 | return render_template('connections.html') 83 | 84 | 85 | @mod.route('/testimonials') 86 | def testimonials(): 87 | return render_template('testimonials.html') 88 | 89 | 90 | @mod.route('/paper-spreadsheet') 91 | def paper_spreadsheet(): 92 | return render_template('paper_spreadsheet.html') 93 | 94 | 95 | @mod.route('/storybook') 96 | def storybook(): 97 | return render_template('storybook.html') 98 | 99 | @mod.route('/remix') 100 | def remix(): 101 | return render_template('remix.html') 102 | -------------------------------------------------------------------------------- /databasic/views/home.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from flask import Blueprint, render_template 3 | 4 | mod = Blueprint('home', __name__, url_prefix='/', template_folder='../templates/home') 5 | 6 | logger = logging.getLogger(__name__) 7 | 8 | @mod.route('/') 9 | def index(): 10 | return render_template('index.html') 11 | -------------------------------------------------------------------------------- /dbutils.py: -------------------------------------------------------------------------------- 1 | from databasic import mongo 2 | import sys 3 | 4 | VALID_COLLECTION_NAMES = ['wordcounter', 'wtfcsv', 'samediff', 'connectthedots'] 5 | 6 | 7 | def main(argv): 8 | if '-rm-samples' in argv: 9 | mongo.remove_all_sample_data() 10 | print('removed sample data') 11 | if '-rm-expired' in argv: 12 | mongo.remove_all_expired_results() 13 | print('removed expired results') 14 | if '-rm-by-id' in argv: 15 | if argv[1] not in VALID_COLLECTION_NAMES: 16 | print("Error - invalid collection name, must be one of {}".format(', '.join(VALID_COLLECTION_NAMES))) 17 | sys.exit(1) 18 | print('removing {} from {}'.format(argv[2], argv[1])) 19 | results = mongo.remove_by_id(argv[1], argv[2]) 20 | print(' removed {} rows'.format(results['n'])) 21 | 22 | 23 | if __name__ == '__main__': 24 | main(sys.argv[1:]) 25 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | python -m scripts.init_samples 4 | -------------------------------------------------------------------------------- /nltk.txt: -------------------------------------------------------------------------------- 1 | punkt 2 | stopwords 3 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | beautifulsoup4==4.10.0 2 | cssmin==0.2.0 3 | csvkit==0.9.2 # can't upgrade csvkit because the API changed a lot at 1.0 (switched to agate) 4 | Flask==2.3.2 5 | Flask-Assets==0.12 6 | Flask-Babel==1.0.0 7 | Flask-DebugToolbar==0.11.0 8 | Flask-Mail==0.9.1 9 | Flask-WTF==1.2.* 10 | gdata-python3==3.0.1 11 | readability-lxml==0.8.1 12 | gspread==4.0.1 13 | gunicorn==20.1.0 14 | jsmin==3.0.1 15 | libsass==0.21.0 16 | natural==0.2.0 17 | networkx==2.8.* 18 | nltk==3.7 19 | numpy==1.22.1 20 | oauth2client==1.5.1 21 | pojson==0.7 22 | pymongo==3.7.1 23 | pytest==7.0.1 24 | pyth3==0.7 25 | python-dateutil==2.2 # have to use this older version for csvkit python -m nltk.downloader all 26 | python-docx==0.8.11 27 | python-louvain==0.16 28 | pytz==2019.1 29 | requests>=2.20.0 30 | scipy==1.7.3 31 | six==1.16.0 32 | SQLAlchemy>=1.3.0 33 | textmining3==1.1.0 34 | docx2txt==0.8 35 | xlrd==2.0.1 36 | -------------------------------------------------------------------------------- /run.py: -------------------------------------------------------------------------------- 1 | from databasic import app 2 | 3 | if __name__ == '__main__': 4 | app.run() 5 | -------------------------------------------------------------------------------- /runtime.txt: -------------------------------------------------------------------------------- 1 | python-3.9.18 2 | -------------------------------------------------------------------------------- /scripts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dataculturegroup/DataBasic/9908b65a1fdd492272c787d5224668bba6de00ce/scripts/__init__.py -------------------------------------------------------------------------------- /scripts/init_samples.py: -------------------------------------------------------------------------------- 1 | import os 2 | import json 3 | import logging 4 | import requests 5 | import tempfile 6 | 7 | 8 | def init_samples(): 9 | """ 10 | Here we need to fetch the sample files and save a path to where they are into the .json file. 11 | TODO: change this later to process them all here into the database so they are no longer lazy-processed? 12 | :return: 13 | """ 14 | print("Trying to get sample files!") 15 | base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 16 | samples_config_file_path = os.path.join(base_dir, 'config', 'sample-data.json') 17 | print("Retrieving sample files from: ", samples_config_file_path) 18 | 19 | # tell the dumb thing this is NOT ASCII 20 | samples = json.load(open(samples_config_file_path, 'r', encoding='utf-8')) 21 | 22 | if os.environ.get('APP_MODE', None) == "development": 23 | # change the paths to absolute ones 24 | for sample in samples: 25 | sample['path'] = os.path.join(base_dir, sample['source']) 26 | print(" Updated sample data with base dir: {}".format(base_dir)) 27 | else: 28 | # copy from server to local temp dir and change to abs paths (to temp dir files) 29 | url_base = os.environ.get('SAMPLE_DATA_SERVER', None) 30 | for sample in samples: 31 | url = url_base + sample['source'] 32 | print(" Loading sample data file: {}".format(url)) 33 | 34 | #reading files as utf-8 35 | 36 | requests.encoding = 'utf-8' 37 | text = requests.get(url).text 38 | 39 | # write files as utf-8 40 | 41 | f = tempfile.NamedTemporaryFile(mode="w", delete=False, encoding='utf-8') 42 | f.write(text) 43 | f.close() 44 | os.chmod(f.name, 0o444) 45 | sample['path'] = f.name 46 | print(" Downloaded sample data and saved to tempdir") 47 | for sample in samples: 48 | file_size = os.stat(sample['path']).st_size 49 | print(" Cached {} bytes of {} to {}".format(file_size, sample['source'], sample['path'])) 50 | 51 | # write it out so the app can load it, with the `path`s we just filled in 52 | json.dump(samples, open(samples_config_file_path, 'w'), ensure_ascii=False) 53 | 54 | 55 | if __name__ == "__main__": 56 | init_samples() 57 | -------------------------------------------------------------------------------- /server.wsgi: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | # add this directory to the python path, so all the import work 5 | basedir = os.path.dirname(os.path.abspath(__file__)) 6 | sys.path.append(basedir) 7 | 8 | # tell wsgi what to use as the application 9 | from databasic import app as application 10 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup,find_packages 2 | 3 | setup( 4 | name='DataBasic', 5 | version='0.8', 6 | long_description=__doc__, 7 | packages=find_packages(), 8 | include_package_data=True, 9 | zip_safe=False, 10 | sass_manifests={ 11 | 'databasic': ('static/sass', 'static/css') 12 | }, 13 | install_requires=['flask','flask_debugtoolbar','flask-uploads','Flask-WTF', 14 | 'Flask-Babel','Flask-Mail','pojson','requests','nltk','docx','unicodecsv', 15 | 'csvkit','xlrd','gspread','gdata','oauth2client','pymongo','celery','redis', 16 | 'pyth','libsass >= 0.6.0','textmining','scipy','numpy','wtforms','kombu','billiard', 17 | 'beautifulsoup4'] 18 | ) -------------------------------------------------------------------------------- /setup.txt: -------------------------------------------------------------------------------- 1 | cp config/development.py.template config/development.py 2 | 3 | pip install virtualenv 4 | 5 | conda create -n databasic anaconda 6 | 7 | conda create -n databasic python=2.7.10 anaconda 8 | source activate databasic 9 | 10 | pip install -r requirements.txt 11 | easy_install --upgrade numpy 12 | 13 | ./start.sh -------------------------------------------------------------------------------- /showlocales.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python3 2 | import subprocess 3 | 4 | def find_locales(): 5 | out = subprocess.run(['locale', '-a'], stdout=subprocess.PIPE).stdout 6 | try: 7 | # Even though I use utf8 on my system output from "locale -a" 8 | # included "bokml" in Latin-1. Then this won't work, but the 9 | # exception will. 10 | res = out.decode('utf-8') 11 | except: 12 | res = out.decode('latin-1') 13 | return res.rstrip('\n').splitlines() 14 | 15 | if __name__ == "__main__": 16 | for loc in find_locales(): 17 | print(loc) -------------------------------------------------------------------------------- /start.sh: -------------------------------------------------------------------------------- 1 | 2 | # have to move back a dir because in development, Flask is also loading the config in instance/ 3 | # for production, in DataBasic/__init__.py set instance_relative_config to False 4 | # and update these paths 5 | 6 | # linux / os x: 7 | export APP_MODE=development 8 | 9 | # windows: 10 | # set APP_CONFIG_FILE=..\config\development.py 11 | 12 | alias activate=". venv/bin/activate" 13 | gunicorn databasic:app --timeout 120 --reload 14 | # wait 15 | # redis-server & celery -A databasic worker --app=databasic.celeryapp --loglevel=debug & python run.py & apid=$!; 16 | # wait; 17 | # while kill -0 $apid; do ps auxww | grep 'celery worker' | awk '{print $2}' | xargs kill -9; done 18 | # redis-cli shutdown 19 | -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | import unittest, logging, os, sys 3 | 4 | from databasic.logic.test.wordhandlertest import * 5 | from databasic.logic.test.filehandlertest import * 6 | from databasic.logic.test.wtfcsvstattest import * 7 | from databasic.logic.test.connectthedotstest import * 8 | from databasic.logic.test.connectthedotsbigdatatest import * 9 | from databasic.logic.test.dbtest import * 10 | 11 | test_classes = [ 12 | WordHandlerTest, 13 | FileHandlerTest, 14 | MongoHandlerTest, 15 | WTFCSVStatTest, 16 | ConnectTheDotsTest, 17 | # ConnectTheDotsBigDataTest 18 | ] 19 | 20 | # set up all logging to DEBUG (cause we're running tests here!) 21 | logging.basicConfig(level=logging.DEBUG) 22 | log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 23 | log_handler = logging.FileHandler(os.path.join('logs/','test.log')) 24 | log_handler.setFormatter(log_formatter) 25 | 26 | # now run all the tests 27 | suites = [ unittest.TestLoader().loadTestsFromTestCase(test_class) for test_class in test_classes ] 28 | 29 | if __name__ == "__main__": 30 | suite = unittest.TestSuite(suites) 31 | test_result = unittest.TextTestRunner(verbosity=2).run(suite) 32 | if not test_result.wasSuccessful(): 33 | sys.exit(1) 34 | -------------------------------------------------------------------------------- /translations-add-language.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pybabel init -i databasic/messages.pot -d databasic/translations -l $1 4 | -------------------------------------------------------------------------------- /translations-compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | LANG=$1 4 | JSONFILE=databasic/translations/${LANG}/LC_MESSAGES/messages.json 5 | 6 | pybabel compile -d databasic/translations 7 | pojson databasic/translations/${LANG}/LC_MESSAGES/messages.po > "${JSONFILE}" 8 | 9 | echo "compiled '${LANG}' translation" 10 | -------------------------------------------------------------------------------- /translations-init-RUN-ONLY-ONCE.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pybabel extract -F config/babel.cfg databasic/ -o databasic/messages.pot 4 | pybabel init -i databasic/messages.pot -d databasic/translations -l es -------------------------------------------------------------------------------- /translations-update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pybabel extract -F config/babel.cfg databasic/ -o databasic/messages.pot 4 | pybabel update -i databasic/messages.pot -d databasic/translations --------------------------------------------------------------------------------