Skip to content

Commit

Permalink
samples UI minor milestone
Browse files Browse the repository at this point in the history
  • Loading branch information
ivelin committed Sep 17, 2019
1 parent cb2529f commit c120682
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 57 deletions.
3 changes: 3 additions & 0 deletions ambianic-attach.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/sh
echo "Attaching shell to a running Ambianic docker image"
docker exec -it ambianic-dev bash
17 changes: 9 additions & 8 deletions ambianic/__init__.py → ambianic/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,6 @@
from .service import ServiceExit, ThreadedJob
import os

def main():
env_work_dir = os.environ.get('AMBIANIC_DIR', os.getcwd())
start(env_work_dir)


if __name__ == '__main__':
main()

WORK_DIR = None
AI_MODELS_DIR = "ai_models"
CONFIG_FILE = "config.yaml"
Expand Down Expand Up @@ -193,3 +185,12 @@ def stop():
log.info("Stopping server...")
global _service_exit_requested
_service_exit_requested = True


def main():
env_work_dir = os.environ.get('AMBIANIC_DIR', os.getcwd())
start(env_work_dir)


if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion ambianic/webapp/client/src/components/HackerNews.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export default {
if (data.hits.length) {
this.page += 1;
this.list.push(...data.hits);
console.debug('this.list hacker news hits: '+ JSON.stringify(this.list));
console.debug('this.list hacker news hits count: '+ JSON.stringify(this.list.length));
$state.loaded();
} else {
$state.complete();
Expand Down
115 changes: 76 additions & 39 deletions ambianic/webapp/client/src/components/Samples.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,55 +14,69 @@
</button>
<br><br>
<table class="table table-hover">
<!--
<thead>
<tr>
<th scope="col">File</th>
<th scope="col">ID</th>
<th scope="col">Datetime</th>
<th scope="col">Image</th>
<th scope="col">Inference Results</th>
<th></th>
</tr>
</thead>
-->
<tbody>
<tr v-for="(sample, index) in samples" :key="index">
<td>{{ sample.file }}</td>
<td>{{ sample.id }}</td>
<td>{{ sample.datetime }}</td>
<td><img :src='imagePath(sample.image)'></img></td>
<td>
<ul v-for="inf in sample.inference_result" :key="index">
<li>
<p>Category: {{inf.category}}</p>
<p>Confidence: {{inf.confidence}}</p>
<p>Box: {{inf.box}}</p>
</li>
</ul>
</td>
<!--
<td>
<span v-if="sample.read">Yes</span>
<span v-else>No</span>
</td>
-->
<td>
<div class="btn-group" role="group">
<button
type="button"
class="btn btn-warning btn-sm"
v-b-modal.sample-update-modal
@click="editSample(sample)">
Update
</button>
<button
type="button"
class="btn btn-danger btn-sm"
@click="onDeleteSample(sample)"
>
Delete
</button>
</div>
</td>
<table>
<tbody>
<tr>
<td><img :src='imagePath(sample.image)'></img></td>
</tr>
<tr>
<td>
<span>{{ sample.file }}</span>
<span>{{ sample.id }}</span>
<span>{{ sample.datetime }}</span>
<span>
<ul v-for="inf in sample.inference_result"
:key="index"
:data-num="index + 1"
>
<li>
<p>Category: {{inf.category}}</p>
<p>Confidence: {{inf.confidence}}</p>
<p>Box: {{inf.box}}</p>
</li>
</ul>
</span>
<!--
<td>
<span v-if="sample.read">Yes</span>
<span v-else>No</span>
</td>
-->
</td>
<td>
<div class="btn-group" role="group">
<button
type="button"
class="btn btn-warning btn-sm"
v-b-modal.sample-update-modal
@click="editSample(sample)">
Update
</button>
<button
type="button"
class="btn btn-danger btn-sm"
@click="onDeleteSample(sample)"
>
Delete
</button>
</div>
</td>
</tr>
</tbody>
</table>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -138,6 +152,7 @@
</b-button-group>
</b-form>
</b-modal>
<infinite-loading :identifier="infiniteId" @infinite="infiniteHandler"></infinite-loading>
</div>
</template>

Expand All @@ -154,6 +169,9 @@ export default {
data() {
return {
samples: [],
// infinite loading attributes
page: 1,
infiniteId: +new Date(),
addSampleForm: {
title: '',
author: '',
Expand All @@ -173,6 +191,25 @@ export default {
alert: Alert,
},
methods: {
infiniteHandler($state) {
const api = API_SAMPLES_PATH
axios.get(api, {
params: {
page: this.page,
},
}).then(({ data }) => {
if (data.samples.length) {
console.debug('this.page: '+ this.page);
this.page += 1;
this.samples.push(...data.samples);
console.debug('data.samples.length: '+ data.samples.length);
console.debug('this.samples.length: '+ this.samples.length);
$state.loaded();
} else {
$state.complete();
}
});
},
imagePath(image_name) {
let p = API_ROOT + 'data/faces/' + image_name;
console.debug('imagePath: ' + p)
Expand Down Expand Up @@ -288,7 +325,7 @@ export default {
},
},
created() {
this.getSamples();
// this.getSamples();
},
};
</script>
8 changes: 7 additions & 1 deletion ambianic/webapp/client/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import App from './App.vue';
import InfiniteLoading from 'vue-infinite-loading';
import router from './router';

Vue.use(InfiniteLoading, { /* options */ });
Vue.use(InfiniteLoading, { /* options */
slots: {
// keep default styles
noResults: 'No data available on your timeline yet.',
noMore: 'End of your timeline archive.',
},
});

Vue.use(BootstrapVue);

Expand Down
7 changes: 5 additions & 2 deletions ambianic/webapp/flaskr.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,11 @@ def get_samples():
response_object['message'] = 'Sample added!'
log.debug('Sample added: %s ', new_sample)
else:
response_object['samples'] = samples.get_samples()
log.debug('Returning samples: %s ', response_object)
req_page = request.args.get('page', default=1, type=int)
resp = samples.get_samples(page=req_page)
response_object['samples'] = resp
log.debug('Returning %d samples', len(resp))
# log.debug('Returning samples: %s ', response_object)
resp = jsonify(response_object)
return resp

Expand Down
20 changes: 14 additions & 6 deletions ambianic/webapp/server/samples.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
]


def get_samples(before_datetime=None, max_count=10):
def get_samples(before_datetime=None, page=1):
"""Get stored pipeline samples.
Parameters
Expand All @@ -65,8 +65,8 @@ def get_samples(before_datetime=None, max_count=10):
It uses python's standard function datetime.fromisoformat().
If not provided, the function will start with the most recent available
sample.
max_count : positive integer
Maximum number of samples returned. Defaults to 10.
page : positive integer
Paginates samples in batches of 5. Defaults to page=1.
Returns
-------
Expand All @@ -75,23 +75,31 @@ def get_samples(before_datetime=None, max_count=10):
"""
parsed_datetime = None
assert isinstance(page, int)
assert page > 0
page_size = 5
if before_datetime:
try:
parsed_datetime = datetime.fromisoformat(before_datetime)
log.debug('Fetching %d samples before %s', max_count,
log.debug('Fetching samples saved before %s',
parsed_datetime)
except ValueError as e:
log.warning('Unable to parse before_datetime parameter: %s. '
' Error: %s', before_datetime, str(e))
page_start_position = (page-1)*page_size
page_end_position = page_start_position + page_size
if not parsed_datetime:
log.debug('Fetching %d most recent samples.', max_count)
log.debug('Fetching most recent saved samples')
log.debug('Fetching samples page %d. Page size %d. '
'Sample index range [%d:%d]. ',
page, page_size, page_start_position, page_end_position)
p = Path('./data/faces/')
log.debug('Samples path: %s', p.resolve())
files = list(p.glob("*-json.txt"))
log.debug('Fetched %d file names.', len(files))
files = sorted(files, key=os.path.getmtime, reverse=True)
samples = []
for json_file in files:
for json_file in files[page_start_position:page_end_position]:
with open(json_file) as f:
sample = json.load(f)
sample['id'] = uuid.uuid4().hex
Expand Down

0 comments on commit c120682

Please sign in to comment.