diff --git a/ambianic-attach.sh b/ambianic-attach.sh new file mode 100755 index 00000000..0a3d330d --- /dev/null +++ b/ambianic-attach.sh @@ -0,0 +1,3 @@ +#!/bin/sh +echo "Attaching shell to a running Ambianic docker image" +docker exec -it ambianic-dev bash diff --git a/ambianic/__init__.py b/ambianic/__main__.py similarity index 99% rename from ambianic/__init__.py rename to ambianic/__main__.py index c29681bc..a8af3fa0 100755 --- a/ambianic/__init__.py +++ b/ambianic/__main__.py @@ -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" @@ -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() diff --git a/ambianic/webapp/client/src/components/HackerNews.vue b/ambianic/webapp/client/src/components/HackerNews.vue index 37987e01..84b1c8bc 100644 --- a/ambianic/webapp/client/src/components/HackerNews.vue +++ b/ambianic/webapp/client/src/components/HackerNews.vue @@ -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(); diff --git a/ambianic/webapp/client/src/components/Samples.vue b/ambianic/webapp/client/src/components/Samples.vue index 5202f2ca..9e2aefbb 100644 --- a/ambianic/webapp/client/src/components/Samples.vue +++ b/ambianic/webapp/client/src/components/Samples.vue @@ -14,55 +14,69 @@

+ - - - - - - - +
{{ sample.file }}{{ sample.id }}{{ sample.datetime }} -
    -
  • -

    Category: {{inf.category}}

    -

    Confidence: {{inf.confidence}}

    -

    Box: {{inf.box}}

    -
  • -
-
-
- - -
-
+ + + + + + + + + +
+ {{ sample.file }} + {{ sample.id }} + {{ sample.datetime }} + +
    +
  • +

    Category: {{inf.category}}

    +

    Confidence: {{inf.confidence}}

    +

    Box: {{inf.box}}

    +
  • +
+
+ +
+
+ + +
+
@@ -138,6 +152,7 @@ + @@ -154,6 +169,9 @@ export default { data() { return { samples: [], + // infinite loading attributes + page: 1, + infiniteId: +new Date(), addSampleForm: { title: '', author: '', @@ -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) @@ -288,7 +325,7 @@ export default { }, }, created() { - this.getSamples(); + // this.getSamples(); }, }; diff --git a/ambianic/webapp/client/src/main.js b/ambianic/webapp/client/src/main.js index 09a43dba..f019a691 100644 --- a/ambianic/webapp/client/src/main.js +++ b/ambianic/webapp/client/src/main.js @@ -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); diff --git a/ambianic/webapp/flaskr.py b/ambianic/webapp/flaskr.py index f09a59b0..458172f2 100755 --- a/ambianic/webapp/flaskr.py +++ b/ambianic/webapp/flaskr.py @@ -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 diff --git a/ambianic/webapp/server/samples.py b/ambianic/webapp/server/samples.py index 3e9eb985..38a8e7da 100644 --- a/ambianic/webapp/server/samples.py +++ b/ambianic/webapp/server/samples.py @@ -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 @@ -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 ------- @@ -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