Repository: chainer/chainerui

Issue:
Assets are not deleted
Even if a project is deleted, asset related with the project is remain on database. When register new project, results show remained assets, not new one.

I'll send a PR from https://github.com/disktnk/chainerui/tree/fix/asset-delete to fix it, after merge #214 , 

Discussion:

Patch:
diff --git a/chainerui/models/__init__.py b/chainerui/models/__init__.py
index d0dc9f0..77c7c1e 100644
--- a/chainerui/models/__init__.py
+++ b/chainerui/models/__init__.py
@@ -1,4 +1,6 @@
 from chainerui.models.argument import Argument  # NOQA
+from chainerui.models.asset import Asset  # NOQA
+from chainerui.models.bindata import Bindata  # NOQA
 from chainerui.models.command import Command  # NOQA
 from chainerui.models.log import Log  # NOQA
 from chainerui.models.project import Project  # NOQA
diff --git a/chainerui/models/result.py b/chainerui/models/result.py
index 0050e7d..ea8932d 100644
--- a/chainerui/models/result.py
+++ b/chainerui/models/result.py
@@ -28,6 +28,7 @@ class Result(database.BASE):
     )
     commands = relationship('Command', cascade='all, delete-orphan')
     snapshots = relationship('Snapshot', cascade='all, delete-orphan')
+    assets = relationship('Asset', cascade='all, delete-orphan')
     log_modified_at = Column(DateTime, default=None)
     created_at = Column(DateTime, default=datetime.datetime.now())
     updated_at = Column(
diff --git a/chainerui/tasks/collect_assets.py b/chainerui/tasks/collect_assets.py
index f74b2af..87b4a77 100644
--- a/chainerui/tasks/collect_assets.py
+++ b/chainerui/tasks/collect_assets.py
@@ -9,7 +9,7 @@ from chainerui.models.bindata import Bindata
 from chainerui import summary
 
 
-def collect_assets(result, assets, force=False):
+def collect_assets(result, force=False):
     """collect assets from meta file
 
     Collecting assets only when the metafile is updated. If number of assets
@@ -17,21 +17,21 @@ def collect_assets(result, assets, force=False):
     """
     path_name = result.path_name
     info_path = os.path.join(path_name, summary.CHAINERUI_ASSETS_METAFILE_NAME)
-    start_idx = len(assets)
     if not os.path.isfile(info_path):
-        return assets
+        return
+    start_idx = len(result.assets)
     file_modified_at = datetime.datetime.fromtimestamp(os.path.getmtime(
         info_path))
     if start_idx > 0:
-        if assets[-1].file_modified_at == file_modified_at:
-            return assets
+        if result.assets[-1].file_modified_at == file_modified_at:
+            return
 
     with open(info_path, 'r') as f:
         info_list = json.load(f, object_pairs_hook=OrderedDict)
 
     if len(info_list) < start_idx:
         start_idx = 0
-        assets = []
+        result.assets = []
 
     for base_info in info_list[start_idx:]:
         asset_path = base_info.pop('images', {})
@@ -45,8 +45,6 @@ def collect_assets(result, assets, force=False):
             content = Bindata(
                 asset_id=asset.id, name=path, tag=key, content=data)
             asset.content_list.append(content)
-        assets.append(asset)
+        result.assets.append(asset)
 
     db.session.commit()
-
-    return assets
diff --git a/chainerui/views/result_asset.py b/chainerui/views/result_asset.py
index c4bd790..d7b63cc 100644
--- a/chainerui/views/result_asset.py
+++ b/chainerui/views/result_asset.py
@@ -5,7 +5,6 @@ from flask import send_file
 from flask.views import MethodView
 
 from chainerui.database import db
-from chainerui.models.asset import Asset
 from chainerui.models.bindata import Bindata
 from chainerui.models.project import Project
 from chainerui.models.result import Result
@@ -37,13 +36,8 @@ class ResultAssetAPI(MethodView):
             }), 404
 
         if content_id is None:
-            assets = db.session.query(Asset).\
-                filter_by(result_id=result_id).\
-                order_by(Asset.id).all()
-            if assets is None:
-                assets = []
-            assets = collect_assets(result, assets)
-            assets_response = [asset.serialize for asset in assets]
+            collect_assets(result)
+            assets_response = [asset.serialize for asset in result.assets]
             for asset in assets_response:
                 for content in asset['contents']:
                     content['uri'] = self._make_content_uri(


Test patch:
diff --git a/tests/tasks_tests/test_collect_assets.py b/tests/tasks_tests/test_collect_assets.py
index cf05c8f..182bcb9 100644
--- a/tests/tasks_tests/test_collect_assets.py
+++ b/tests/tasks_tests/test_collect_assets.py
@@ -57,13 +57,14 @@ def test_collect_assets_no_meta(func_dir):
     os.remove(os.path.join(func_dir, summary.CHAINERUI_ASSETS_METAFILE_NAME))
     result = _get_dummy_result(func_dir)
 
-    actual_list = collect_assets.collect_assets(result, [])
-    assert len(actual_list) == 0
+    collect_assets.collect_assets(result)
+    assert len(result.assets) == 0
 
 
 def test_collect_assets(func_dir):
     result = _get_dummy_result(func_dir)
-    actual_list = collect_assets.collect_assets(result, [])
+    collect_assets.collect_assets(result)
+    actual_list = result.assets
 
     assert len(actual_list) == 2
     actual_img1 = actual_list[0]
@@ -96,17 +97,19 @@ def test_collect_assets(func_dir):
 
 def test_collect_assets_no_updated(func_dir):
     result = _get_dummy_result(func_dir)
-    first_assets = collect_assets.collect_assets(result, [])
+    collect_assets.collect_assets(result)
+    first_assets = result.assets
     assert len(first_assets) == 2
 
-    second_assets = collect_assets.collect_assets(result, first_assets)
-    assert first_assets == second_assets
+    collect_assets.collect_assets(result, first_assets)
+    assert first_assets == result.assets
 
 
 def test_collect_assets_updated(func_dir):
     info_path = os.path.join(func_dir, summary.CHAINERUI_ASSETS_METAFILE_NAME)
     result = _get_dummy_result(func_dir)
-    first_assets = collect_assets.collect_assets(result, [])
+    collect_assets.collect_assets(result)
+    first_assets = result.assets
     assert len(first_assets) == 2
 
     with open(os.path.join(func_dir, 'img1_3.png'), 'w') as f:
@@ -124,7 +127,8 @@ def test_collect_assets_updated(func_dir):
     with open(info_path, 'w') as f:
         json.dump(meta, f)
 
-    second_assets = collect_assets.collect_assets(result, first_assets)
+    collect_assets.collect_assets(result)
+    second_assets = result.assets
     assert len(second_assets) == 3
 
     actual_img3 = second_assets[2]
@@ -142,7 +146,8 @@ def test_collect_assets_updated(func_dir):
 def test_collect_assets_new_meta(func_dir):
     info_path = os.path.join(func_dir, summary.CHAINERUI_ASSETS_METAFILE_NAME)
     result = _get_dummy_result(func_dir)
-    first_assets = collect_assets.collect_assets(result, [])
+    collect_assets.collect_assets(result)
+    first_assets = result.assets
     assert len(first_assets) == 2
 
     test_data = [
@@ -157,7 +162,8 @@ def test_collect_assets_new_meta(func_dir):
     ]
     with open(info_path, 'w') as f:
         json.dump(test_data, f)
-    second_assets = collect_assets.collect_assets(result, first_assets)
+    collect_assets.collect_assets(result)
+    second_assets = result.assets
     assert len(second_assets) == 1
     actual_img1 = second_assets[0]
     assert len(actual_img1.content_list) == 2