Repository: pypi/warehouse

Issue:
Display project/release journal
Sub ticket of #2734 

We should show the maintainer some history of their project/release.  The current UI looks like this:

![screenshot from 2018-01-31 21-37-45](https://user-images.githubusercontent.com/3323703/35649542-54b93e60-06d1-11e8-9876-2cffb6ba3e87.png)

Questions:

- Should this be on a project level?
- Should this be on a release level?
- Should it be on *both*?
- What milestone should it be in?

On the last question, it's probably not a heap of work for me to get it into the maintainer MVP - so long as the data is ready to go :)

ping @di @ewdurbin @brainwane @dstufft 


Discussion:
from @di (https://github.com/pypa/warehouse/issues/2807#issuecomment-362085418)

> Hmm, looks like I'm wrong -- legacy PyPI actually does show a mix of project-level journal entries and release-level journal entries on each release page.
>
> This seems like it would be somewhat confusing to users. IMO it'd be better to have all the journal entries in one place, but perhaps I'm missing something obvious and @ewdurbin can chime in and explain why it's like that on legacy.
I put this in the Maintainer MVP milestone, since it already exists (in some form) on legacy.

Resolving patch:
diff --git a/warehouse/manage/views.py b/warehouse/manage/views.py
--- a/warehouse/manage/views.py
+++ b/warehouse/manage/views.py
@@ -462,3 +462,22 @@ def delete_project_role(project, request):
     return HTTPSeeOther(
         request.route_path('manage.project.roles', project_name=project.name)
     )
+
+
+@view_config(
+    route_name="manage.project.history",
+    renderer="manage/history.html",
+    uses_session=True,
+    permission="manage",
+)
+def manage_project_history(project, request):
+    journals = (
+        request.db.query(JournalEntry)
+        .filter(JournalEntry.name == project.name)
+        .order_by(JournalEntry.submitted_date.desc())
+        .all()
+    )
+    return {
+        'project': project,
+        'journals': journals,
+    }
diff --git a/warehouse/routes.py b/warehouse/routes.py
--- a/warehouse/routes.py
+++ b/warehouse/routes.py
@@ -162,6 +162,13 @@ def includeme(config):
         traverse="/{project_name}",
         domain=warehouse,
     )
+    config.add_route(
+        "manage.project.history",
+        "/manage/project/{project_name}/history/",
+        factory="warehouse.packaging.models:ProjectFactory",
+        traverse="/{project_name}",
+        domain=warehouse,
+    )
 
     # Packaging
     config.add_route(


Test patch:
diff --git a/tests/unit/manage/test_views.py b/tests/unit/manage/test_views.py
--- a/tests/unit/manage/test_views.py
+++ b/tests/unit/manage/test_views.py
@@ -10,6 +10,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import datetime
 import uuid
 
 import pretend
@@ -22,7 +23,9 @@
 from warehouse.accounts.interfaces import IUserService
 from warehouse.packaging.models import JournalEntry, Project, Role
 
-from ...common.db.packaging import ProjectFactory, RoleFactory, UserFactory
+from ...common.db.packaging import (
+    JournalEntryFactory, ProjectFactory, RoleFactory, UserFactory,
+)
 
 
 class TestManageProfile:
@@ -974,3 +977,22 @@ def test_delete_own_owner_role(self, db_request):
         ]
         assert isinstance(result, HTTPSeeOther)
         assert result.headers["Location"] == "/the-redirect"
+
+
+class TestManageProjectHistory:
+
+    def test_get(self, db_request):
+        project = ProjectFactory.create()
+        older_journal = JournalEntryFactory.create(
+            name=project.name,
+            submitted_date=datetime.datetime(2017, 2, 5, 17, 18, 18, 462634),
+        )
+        newer_journal = JournalEntryFactory.create(
+            name=project.name,
+            submitted_date=datetime.datetime(2018, 2, 5, 17, 18, 18, 462634),
+        )
+
+        assert views.manage_project_history(project, db_request) == {
+            'project': project,
+            'journals': [newer_journal, older_journal],
+        }
diff --git a/tests/unit/test_routes.py b/tests/unit/test_routes.py
--- a/tests/unit/test_routes.py
+++ b/tests/unit/test_routes.py
@@ -196,6 +196,13 @@ def add_policy(name, filename):
             traverse="/{project_name}",
             domain=warehouse,
         ),
+        pretend.call(
+            "manage.project.history",
+            "/manage/project/{project_name}/history/",
+            factory="warehouse.packaging.models:ProjectFactory",
+            traverse="/{project_name}",
+            domain=warehouse,
+        ),
         pretend.call(
             "packaging.project",
             "/project/{name}/",