Browse Source

Initial version of application

master
Brett Langdon 8 years ago
commit
7256529be6
No known key found for this signature in database GPG Key ID: B664881177781B04
7 changed files with 458 additions and 0 deletions
  1. +1
    -0
      .gitignore
  2. +13
    -0
      Pipfile
  3. +244
    -0
      Pipfile.lock
  4. +116
    -0
      app.js
  5. +1
    -0
      imdb-top-250.json
  6. +33
    -0
      index.html
  7. +50
    -0
      upload.py

+ 1
- 0
.gitignore View File

@ -0,0 +1 @@
service.json

+ 13
- 0
Pipfile View File

@ -0,0 +1,13 @@
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"
[packages]
requests = "*"
firebase-admin = "*"
[dev-packages]
[requires]
python_version = "3.6"

+ 244
- 0
Pipfile.lock View File

@ -0,0 +1,244 @@
{
"_meta": {
"hash": {
"sha256": "a8f9f7cbbcf53e5965319c4f459b9dc53aa90ccb3bdf1f17b8e40c821010bda9"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.6"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.python.org/simple",
"verify_ssl": true
}
]
},
"default": {
"cachecontrol": {
"hashes": [
"sha256:a7d21ba4e3633d95ac9fed5be205ee6d1da36bdc4b8914eb7a57ff50b7e5628c"
],
"version": "==0.12.4"
},
"cachetools": {
"hashes": [
"sha256:4319bbb78172e7bcf99423e1ecd6914b32336ccfe97d2058ffe62e641a7f3abe",
"sha256:ede01f2d3cbd6ddc9e35e16c2b0ce011d8bb70ce0dbaf282f5b4df24b213bc5d"
],
"version": "==2.0.1"
},
"certifi": {
"hashes": [
"sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7",
"sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0"
],
"version": "==2018.4.16"
},
"chardet": {
"hashes": [
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
],
"version": "==3.0.4"
},
"firebase-admin": {
"hashes": [
"sha256:6d67afca16d97e4c6fe3734692a2e2faba3f21ab02077399c8557b4fd702a94c",
"sha256:a19c8e23c3ab399a41eef571189636a3fccf6f88a962f6a2e89d98af0c63aef5"
],
"index": "pypi",
"version": "==2.10.0"
},
"google-api-core": {
"hashes": [
"sha256:2000963305e95410a66e6ef6cfcc9f4627a4a95cb1c10abc98268814f2a6cd80",
"sha256:53e9366ccdb942bcf48e6e8b237d46508dd9dac4c77f35f580140ea83d1a092e"
],
"version": "==1.1.2"
},
"google-auth": {
"hashes": [
"sha256:34088434cb2a2409360b8f3cbc04195a465df1fb2aafad71ebbded77cbf08803",
"sha256:9051802d3dae256036cca9e34633a32c0ed1427730d4ebc513dff91ec8b6dd45"
],
"version": "==1.4.1"
},
"google-cloud-core": {
"hashes": [
"sha256:0090df83dbc5cb2405fa90844366d13176d1c0b48181c1807ab15f53be403f73",
"sha256:89e8140a288acec20c5e56159461d3afa4073570c9758c05d4e6cb7f2f8cc440"
],
"version": "==0.28.1"
},
"google-cloud-firestore": {
"hashes": [
"sha256:a71e36aa39771e51555c3cd9a6bd86f0cc016cef203edda9b0e8fc25f2090211",
"sha256:e34c3d45a3deb0af92cbde769f14ab54fdec7c5cd21b5f49a73cf9b9d3f8d342"
],
"version": "==0.29.0"
},
"google-cloud-storage": {
"hashes": [
"sha256:72b45ba5ce1f57fe74fb35cde1615b32aa9483643330dccdd9e77dab23737193",
"sha256:af3cdf4807f78d04b22fe89cbc8a129342d679932e8acecb02fdebde69f047f3"
],
"version": "==1.9.0"
},
"google-resumable-media": {
"hashes": [
"sha256:116de90b9cd483b17c53618ee6a5a20f33e741c648140c8cc9c2141e07616ff1",
"sha256:97de518f8166d442cc0b61fab308bcd319dbb970981e667ec8ded44f5ce49836"
],
"version": "==0.3.1"
},
"googleapis-common-protos": {
"hashes": [
"sha256:c075eddaa2628ab519e01b7d75b76e66c40eaa50fc52758d8225f84708950ef2"
],
"version": "==1.5.3"
},
"grpcio": {
"hashes": [
"sha256:03522ca2b80cc83c407d6d5fa0f532fc5b0160f5861ab6628ae418218022f339",
"sha256:0c07fc5a9fa73832bca228d9004dc0a511d1f1a890c8ff0fb6e78f7fa1b96d58",
"sha256:5487948a33ded0577035fb9ad5c542463fabdb356d27fb6cf3eed0bed78f5228",
"sha256:592b14bab2cf8a5ac6e0b1e763b10828dda55ae74e4a476102897a25d033d0b8",
"sha256:6727633444344e14d499f81e41e87de29f42653a0c048c0fce780b29e2ffe563",
"sha256:7aaa523dd5e91acb61d41232eef96192a66b1e8d85d79a55a204093dce50b696",
"sha256:7e81d2cd63fbc77782b140d728a5444c09a7ef1ea99957c490b722e416671921",
"sha256:89b96cb00db3e4c2f612ddff81b27afd2406bf697f0654dcd5ba7bed3d5b9322",
"sha256:a26d32bdc1479c3983194ad380e4cc4bad379729fac4d4acbbda209658d65610",
"sha256:b092361aed6a5ab201e750ccc2fc59250448107cb958c63194455fd5161f3dcc",
"sha256:bef5ce5cfe622830da8b92420748e7f5719d208198d750eb497a74fa20da5907",
"sha256:c0232401d096d9beb06d1af42cf3d65bcc790557712c8b0226809c27401dd455",
"sha256:cf6e88dc0fc06e446c689304bae6cc15df0517f02ee2ac52bcef0cb893b3e9ba",
"sha256:cfc2595325ac3bbd170293050a3ff0b5c8e3846d8498d9b2dedcd3063460c007",
"sha256:d4d4eb072fa2c44a8fe22475874c13c2cc786dba587f633cd47720fb8fec922e",
"sha256:d78d29295723493327c68aa39407ec44ed7a4ed326dde413cce57e2409683f68",
"sha256:d829735b1862687074ef9df15f6c4fc1f3b27c0c80d4890ef985c039cdb256c6",
"sha256:db2430e38a268e64c980e34a62b7f50365a4401172a2f5202ad05eb156e418da",
"sha256:df3f75f88431da28b1c60a043f2a4f2e359287249baf317f4eda20626b34ce5d",
"sha256:e1a648519db0de7bab3583dc2471f4c12ee3fc8a8c459e75da9e05ae70cf9ce7",
"sha256:e35e4c0e5fe5f0fd8914a1630443f7272a752fb9d39c96771799a32056b06ab5",
"sha256:e9b09fbae7bcc1b1791168665c29bcf37253f54d9d5e6bc8a533a9917912f1f6",
"sha256:e9b9e67059c81f5b232991c573601856065562f010b655b3afd7ab38459ac321",
"sha256:e9cf01192ed663a277b64bc559066b07a1355cd85b74cbca9353a25e8bd45544",
"sha256:ef886f8c845ce7c011b2c154fd2b7998f920d145a2dfa121459e8df5b562a879",
"sha256:efcf5ea73af68e110c375173495f36d9ed1e50bc88eeae1314f5573f750eecb9",
"sha256:fc4deee5b4402c4bd37b3c7dbcde8903be89b9026af0f5777f63ae24069cafec"
],
"version": "==1.11.0"
},
"idna": {
"hashes": [
"sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f",
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4"
],
"version": "==2.6"
},
"msgpack-python": {
"hashes": [
"sha256:378cc8a6d3545b532dfd149da715abae4fda2a3adb6d74e525d0d5e51f46909b"
],
"version": "==0.5.6"
},
"protobuf": {
"hashes": [
"sha256:01ccd6d03449ae75b779fb5bf4ed62177d61afe3c5e6465ccf3f8b2e1a84afbe",
"sha256:1d92cc30b0b46cced33adde5853d920179eb5ea8eecdee9552502a7f29cc3f21",
"sha256:242e4c7ae565267a8bc8b92d707177f915607ea4bd73244bec6cbf4a49b96661",
"sha256:3b60685732bd0cbdc802dfcb6071efbcf5d927ce3127c13c33ea1a8efae3aa76",
"sha256:3f655e1f99c3e14d56ca900af1b9a4715b691319a295cc38939d7f77eabd5e7c",
"sha256:560a38e692a69957a70ba0e5839aa67430efd63072bf91b0539dac19055694cd",
"sha256:5c1c8f6a0a68a874e3beff89255959dd80fad45870e96c88944a1b81a22dd5f5",
"sha256:628a3bf0794a8b3cabb18db11eb67cc10e0cc6e5525d557ae7b682bb73fa2018",
"sha256:7222d6616108b33ad6cbeff8117062a73c43cdc8fa8f64f6a322ebeb663e710e",
"sha256:76ef6ca3c50e4cfd044861586d5f1b352e0fe7f17f883df6c165bad5b4d0e10a",
"sha256:7c193e6964e752bd056735594826c5b03274ceb8f07349d3ae47d9766250ba96",
"sha256:869e12bcfb5759e683f53ec1dd6155b7be034065431da289f0cb4510040a0799",
"sha256:905414e5ea6cdb78d8730f66335755152b46685fcb9fc2f2134024e3ea9e8dcc",
"sha256:ac0067e3c60737865ed72bb7416e02297d229d960902802d874c0e167128c809",
"sha256:adf716a89c9cc1891ead79a861c427071ef59172f0e11967b00565a9547b3bd0",
"sha256:bcfa99f5a82f5eaaf6e5cee5bfdca5a1670f5740aec1d93dae170645ed1a16b0",
"sha256:cc94079ae6cbcea5ae194464a30f3223f075e06a0446f52bca9ddbeb6e9f412a",
"sha256:d5d9edfdc5a3a01d06062d677b121081629782edf0e05ca1be14f15bb947eeee",
"sha256:e269ab7a50bf0fa6fe6a88ea7dcc7a1079ae9450d9ab9b7730ac32916d55508b",
"sha256:e7fd33a3474cbe18fd5b5620784a0fa21fcae3e402b1806e29c6b450c7f61706"
],
"version": "==3.5.2.post1"
},
"pyasn1": {
"hashes": [
"sha256:0d7f6e959fe53f3960a23d73f35e1fce61348b30915b6664309ca756de7c1f89",
"sha256:5a0db897b311d265cde49615cf783f1c78613138605cdd0f907ecfa5b2aba3ee",
"sha256:758cb50abddc03e4563fd9e7f03db56e3e87b58c0bd01247360326e5c0c7ffa5",
"sha256:7d626683e3d792cccc608da02498aff37ab4f3dafd8905d6bf755d11f9b26b43",
"sha256:a7efe807c4b83a859e2735c692b92ed7b567cfddc4163763412920041d876c2b",
"sha256:b5a9ca48055b9a20f6d1b3d68e38692e5431c86a0f99ea602e61294e891fee5b",
"sha256:c07d6e587b2f928366b1f67c09bda026a3e6fcc99e80a744dc67f8fca3895626",
"sha256:d258b0a71994f7770599835249cece1caef3c70def868c4915e6e5ca49b67d15",
"sha256:d5cd6ed995dba16fad0c521cfe31cd2d68400b53fcc2bce93326829be73ab6d1",
"sha256:d84c2aea3cf43780e9e6a19f4e4dddee9f6976519020e64e47c57e5c7a8c3dd2",
"sha256:e85895087905c65b5b594eb91f7522664c85545b147d5f4d4e7b1b07da8dcbdc",
"sha256:f81c96761fca60d64b1c9b79ec2e40cf9495a745cf570613079ef324aeb9672b"
],
"version": "==0.4.2"
},
"pyasn1-modules": {
"hashes": [
"sha256:041e9fbafac548d095f5b6c3b328b80792f006196e15a232b731a83c93d59493",
"sha256:0cdca76a68dcb701fff58c397de0ef9922b472b1cb3ea9695ca19d03f1869787",
"sha256:0cea139045c38f84abaa803bcb4b5e8775ea12a42af10019d942f227acc426c3",
"sha256:0f2e50d20bc670be170966638fa0ae603f0bc9ed6ebe8e97a6d1d4cef30cc889",
"sha256:47fb6757ab78fe966e7c58b2030b546854f78416d653163f0ce9290cf2278e8b",
"sha256:598a6004ec26a8ab40a39ea955068cf2a3949ad9c0030da970f2e1ca4c9f1cc9",
"sha256:72fd8b0c11191da088147c6e4678ec53e573923ecf60b57eeac9e97433e09fc2",
"sha256:854700bbdd01394e2ada9c1bfbd0ed9f5d0c551350dbbd023e88b11d2771ae06",
"sha256:af00ea8f2022b6287dc375b2c70f31ab5af83989fc6fe9eacd4976ce26cd7ccc",
"sha256:b1f395cae2d669e0830cb023aa86f9f283b7a9aa32317d7f80d8e78aa2745812",
"sha256:c6747146e95d2b14cc2a8399b2b0bde3f93778f8f9ec704690d2b589c376c137",
"sha256:f53fe5bcebdf318f51399b250fe8325ef3a26d927f012cc0c8e0f9e9af7f9deb"
],
"version": "==0.2.1"
},
"pytz": {
"hashes": [
"sha256:65ae0c8101309c45772196b21b74c46b2e5d11b6275c45d251b150d5da334555",
"sha256:c06425302f2cf668f1bba7a0a03f3c1d34d4ebeef2c72003da308b3947c7f749"
],
"version": "==2018.4"
},
"requests": {
"hashes": [
"sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
"sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
],
"index": "pypi",
"version": "==2.18.4"
},
"rsa": {
"hashes": [
"sha256:25df4e10c263fb88b5ace923dd84bf9aa7f5019687b5e55382ffcdb8bede9db5",
"sha256:43f682fea81c452c98d09fc316aae12de6d30c4b5c84226642cf8f8fd1c93abd"
],
"version": "==3.4.2"
},
"six": {
"hashes": [
"sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9",
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb"
],
"version": "==1.11.0"
},
"urllib3": {
"hashes": [
"sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
"sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
],
"version": "==1.22"
}
},
"develop": {}
}

+ 116
- 0
app.js View File

@ -0,0 +1,116 @@
// Initialize Firebase
var config = {
apiKey: "AIzaSyBfECPzG1IA8g1otya4h5wMeYtK2L1AyEk",
authDomain: "autocomplete-8edab.firebaseapp.com",
databaseURL: "https://autocomplete-8edab.firebaseio.com",
projectId: "autocomplete-8edab",
storageBucket: "",
messagingSenderId: "797593136449"
};
firebase.initializeApp(config);
var db = firebase.firestore();
db.settings({ timestampsInSnapshots: true });
var searchTimeout = null;
var resultsElm = document.getElementById('results');
document.querySelector('input').addEventListener('keyup', function (evt) {
var elm = evt.target;
var queryString = elm.value.trim();
if (queryString.length < 2) {
results.innerHTML = '';
return;
}
queryString = queryString.toLowerCase();
var query = db.collection('movies');
var parts = queryString.split(' ');
var valid = false;
for (var i = 0; i < parts.length; i += 1) {
var part = parts[i].trim();
if (part.length < 2) {
continue;
}
valid = true;
query = query.where('terms.' + part, '==', true);
}
if (!valid) {
results.innerHTML = '';
return;
}
// Use `setTimeout` to debounce our api calls
clearTimeout(searchTimeout);
searchTimeout = setTimeout(function () {
elm.parentElement.classList.add('is-loading');
query
.get()
.then(function (docs) {
if (docs.empty) {
results.innerHTML = '<div class="notification is-danger">No results found for query "' + queryString + '"</div>';
return;
}
// Collect the data of our documents into an array
var data = [];
for (var i = 0; i < docs.size; i += 1) {
var doc = docs.docs[i];
data.push(doc.data());
}
// Sort our array by my popular movie first
data.sort(function (a, b) {
if (a.imdb_position < b.imdb_position) return -1;
if (a.imdb_position > b.imdb_position) return 1;
return 0;
});
// Render our results
// Table
var table = document.createElement('table');
table.classList.add('table');
table.classList.add('is-striped');
// Heading row
var thead = document.createElement('thead');
table.appendChild(thead);
var tr = document.createElement('tr');
thead.appendChild(tr);
var th = document.createElement('th');
th.innerText = 'Position';
thead.appendChild(th);
th = document.createElement('th');
th.innerText = 'Title';
thead.appendChild(th);
th = document.createElement('th');
th.innerText = 'Released';
thead.appendChild(th);
for (var i = 0; i < data.length; i += 1) {
var doc = data[i];
tr = document.createElement('tr');
var td = document.createElement('td');
td.innerText = doc.imdb_position;
tr.appendChild(td);
td = document.createElement('td');
td.innerText = doc.title;
tr.appendChild(td);
td = document.createElement('td');
td.innerText = doc.released;
tr.appendChild(td);
table.appendChild(tr);
}
results.innerHTML = '';
results.appendChild(table);
})
.finally(function () {
elm.parentElement.classList.remove('is-loading');
});
}, 300);
});

+ 1
- 0
imdb-top-250.json
File diff suppressed because it is too large
View File


+ 33
- 0
index.html View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Firestore autocomplete example</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
<script defer src="https://use.fontawesome.com/releases/v5.0.7/js/all.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.13.0/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/4.13.0/firebase-firestore.js"></script>
</head>
<body>
<section class="section">
<div class="container content">
<h1 class="title">
Firestore autocomplete example
</h1>
<form>
<div class="field">
<div class="control has-icons-left">
<input type="text" class="input" placeholder="IMDB Top 250 Movie Title..." />
<span class="icon is-small is-left">
<i class="fas fa-search"></i>
</span>
</div>
</div>
</form>
<div id="results"></div>
</div>
</section>
<script src="app.js"></script>
</body>
</html>

+ 50
- 0
upload.py View File

@ -0,0 +1,50 @@
#!/usr/bin/env python
import json
import re
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore
cred = credentials.Certificate('service.json')
firebase_admin.initialize_app(cred)
db = firestore.client()
moviesRef = db.collection('movies')
def get_terms(title):
title = title.strip().lower()
title = re.sub(r'[^\w]', ' ', title)
title = re.sub(r'\s+', ' ', title)
parts = title.split(' ')
terms = dict()
for part in parts:
part = part.strip()
if not part or len(part) < 2:
continue
for i in range(2, len(part) + 1):
terms[part[:i]] = True
return terms
def main():
with open('./imdb-top-250.json') as fp:
movies = json.load(fp)
for movie in movies:
# Convert `imdb_position` to an `int`
movie['imdb_position'] = int(movie['imdb_position'])
# Add our autocomplete terms
movie['terms'] = get_terms(movie['title'])
print('Uploading:', movie['title'], '-', movie['imdb_position'], '-', set(movie['terms'].keys()))
# Create the new document
moviesRef.document().set(movie)
if __name__ == '__main__':
main()

Loading…
Cancel
Save