[
  {
    "path": ".bowerrc",
    "content": "{\n  \"directory\": \"app/static/libs\"\n}\n"
  },
  {
    "path": ".gitignore",
    "content": "app/static/libs/\napp/static/js/\nnode_modules\n.DS_Store\n.module-cache\nGruntfile.js\npackage.json"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Abhinay Omkar\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Procfile",
    "content": "web: gunicorn app:app --log-file=-"
  },
  {
    "path": "README.md",
    "content": "Flask React\n===========\n\nIntroduction\n------------\nBoilerplate to create a simple web app with Flask and React. Other fontend libraries included Twitter Bootstrap, jQuery, Lodash, Require.js & Font Awesome.\n\nDemo\n----\nDeployed on Heroku: [flask-react.herokuapp.com](http://flask-react.herokuapp.com)\n\nInstallation\n------------\n* Install python dependencies\n\t\n\t\tpip install flask requests \n\n* Install required frontend libraries using [bower](http://bower.io/#install-bower).\n\t\t\n\t\tbower install \n\n* Transform JSX to JS using [React tool](http://facebook.github.io/react/docs/tooling-integration.html#productionizing-precompiled-jsx) for development purpose\n\t\t\n\t\tjsx --watch app/static/jsx app/static/js\n\t\t\n* Run Flask server\n\t\t\n\t\tpython app/main.py\n\t\t\n* Start coding! :)\n\nAuthor\n------\nAbhinay Omkar <abhiomkar@gmail.com>\n\nLicense\n-------\nMIT\n\nTODO\n----\n\n- Migrate to ES6. Get rid of deprecated JSX.\n- Support server side rendering of React components\n- Use webpack & gulp for packaging and building.\n- Use PostCSS.\n- Add deploy instructions.\n"
  },
  {
    "path": "app/__init__.py",
    "content": "import requests\nimport os\nimport json\n\nfrom flask import Flask, Response, request, session, g, redirect, url_for, abort, render_template, flash\nfrom urlparse import urljoin\n\napp = Flask(__name__)\n\n@app.route(\"/\")\ndef index():\n    return render_template('base.html')\n\n@app.route('/api/<path:path>', methods=['GET'])\ndef api(path):\n    clientToken = ''\n    clientSecret = ''\n    baseUrl = 'https://suggestqueries.google.com'\n    accessToken = ''\n\n    # Authentication\n    #\n    # session.auth = EdgeGridAuth (\n    #     client_token = clientToken,\n    #     client_secret = clientSecret,\n    #     access_token = accessToken\n    # )\n\n    r = requests.get(urljoin(baseUrl, path), params=request.args)\n\n    if r.status_code != requests.codes.ok:\n        return None\n\n    return Response(r.content,  mimetype='application/json')\n\nif __name__ == \"__main__\":\n    app.run(debug=True)\n"
  },
  {
    "path": "app/static/css/main.css",
    "content": "@import '../libs/bootstrap/dist/css/bootstrap.min.css';\n@import '../libs/font-awesome/css/font-awesome.css';\n\n@import 'styles.css';"
  },
  {
    "path": "app/static/css/styles.css",
    "content": ".r-container {\n\tmargin: auto;\n\twidth: 400px;\n\tmargin-top: 200px;\n}\n\n.r-container h1 {\n\tfont-family: 'Helvetica Nueu', Helvetica, Arial, sans-serif;\n\tfont-weight: 300;\n\tfont-size: 16px;\n\tcolor: #3F3F3F;\n}\n\n.r-container > input {\n\twidth: 100%;\n\tfont-size: 15px;\n\tfont-weight: 300;\n\tborder: 1px solid #cdcdcd;\n\tpadding: 6px;\n\toutline: 0;\n}\n\n.r-container > input:hover, .r-container > input:active, .r-container > input:focus {\n\tborder: 1px solid #bbb;\n}\n\n.r-container > ul.list {\n\tmargin: 0;\n\tpadding: 0;\n\tlist-style: none;\n\tborder-left: 1px solid #cdcdcd;\n\tborder-bottom: 1px solid #cdcdcd;\n\tborder-right: 1px solid #cdcdcd;\n\tbox-shadow: 1px 1px 3px #cdcdcd;\n\toverflow: scroll;\n}\n\n.r-container > ul.list a {\n\tcursor: default;\n\tcolor: #333;\n\tpadding-left: 7px;\n\tpadding-right: 7px;\n\tdisplay: block;\n}\n\n.r-container > ul.list a:hover {\n\ttext-decoration: none;\n\tbackground: #f1f1f1;\n}"
  },
  {
    "path": "app/static/jsx/components/App.js",
    "content": "/** @jsx React.DOM */\n\ndefine([\n    'react',\n], function(React) {\n    var App = React.createClass({\n        getInitialState: function() {\n            return {\n                suggestions: []\n            }\n        },\n\n        getAutoSuggestions: function(keywords) {\n            /*\n                @keywords - array of keywords\n\n                Returns:\n                JSON Response\n            */\n\n            var self = this;\n\n            if (_.isArray(keywords)) {\n                this._xhr = $.get('/api/complete/search?client=firefox&q=' + keywords.join('+'), function(data) {\n                    self.setState({suggestions: data[1]})\n                });\n            }\n            else {\n                return false;\n            }\n        },\n\n        handleChange: function(e) {\n            var keywords = e.target.value.match(/\\S+/g),\n                self = this;\n\n            // clear timeout if timeout is already set\n            if (this._t) {\n                clearTimeout(this._t);\n            }\n\n            // abort any ajax calls\n            if (this._xhr) {\n                this._xhr.abort();\n            }\n\n            // if no keywords then set the suggestions to empty array\n            if (keywords === null) {\n                this.setState({suggestions: []});\n            }\n            else {\n                this._t = setTimeout(function() { self.getAutoSuggestions(keywords) }, 500);\n            }\n        },\n\n        render: function() {\n            var suggestions = [];\n\n            _.forEach(this.state.suggestions, function(s, i) {\n                suggestions.push(<li key={i}><a>{s}</a></li>);\n            })\n\n            return (<div className='r-container'>\n                        <h1>Google Auto Suggestion</h1>\n                        <input autoFocus autoComplete='off' type='text' onChange={this.handleChange} defaultValue='' placeholder='type something here...' />\n                        {suggestions.length > 0 ? <ul className='list'>{suggestions}</ul> : null}\n                    </div>);\n        }\n    });\n\n    return App;\n});"
  },
  {
    "path": "app/static/jsx/main.js",
    "content": "require.config({\n\tpaths: {\n\t\treact: '../libs/react/react',\n\t\tjquery: '../libs/jquery/dist/jquery.min',\n\t\tlodash: '../libs/lodash/dist/lodash.min',\n\t\tbootstrap: '../libs/bootstrap/dist/js/bootstrap.min'\n\t},\n\n\tshim: {\n\t\treact: {\n\t\t\texports: 'React'\n\t\t},\n\n\t\tjquery: {\n\t\t\texports: '$'\n\t\t},\n\n\t\tlodash: {\n\t\t\texports: '_'\n\t\t},\n\n\t\tbootstrap: {\n\t\t\tdeps: ['jquery']\n\t\t}\n\t}\n});\n\nrequire([\n\t'react',\n\t'components/App',\n\t'jquery',\n\t'lodash',\n\t'bootstrap'\n\t],\nfunction(React, App) {\n\tReact.renderComponent(App(), document.getElementById('app'));\n});"
  },
  {
    "path": "app/templates/base.html",
    "content": "<!DOCTYPE html>\n\n<html>\n\t<head>\n\t\t<!-- stylesheets -->\n\t\t<link rel='stylesheet' href='/static/css/main.css' />\n\n\t    <!-- Javascript -->\n\t\t<script data-main='/static/js/main' src='/static/libs/requirejs/require.js'></script>\n\t</head>\n\n\t<body>\n\t\t<div id='app'></div>\n\t</body>\n</html>"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"Flask React\",\n  \"version\": \"0.1.0\",\n  \"authors\": [\n    \"Abhinay Omkar <abhiomkar@gmail.com>\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"libs\",\n    \"test\",\n    \"tests\"\n  ],\n  \"dependencies\": {\n    \"bootstrap\": \"~3.2.0\",\n    \"jquery\": \"~2.1.1\",\n    \"requirejs\": \"~2.1.15\",\n    \"react\": \"~0.11.1\",\n    \"font-awesome\": \"~4.2.0\"\n  }\n}\n"
  },
  {
    "path": "requirements.txt",
    "content": "Flask==0.10.1\nJinja2==2.7.3\nMarkupSafe==0.23\nWerkzeug==0.9.6\ngunicorn==19.1.1\nitsdangerous==0.24\nrequests==2.4.1\nwsgiref==0.1.2\n"
  }
]