We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Display number of docs and messages per source in source list
> At the moment each source in the list displays: source codename, last updated. It would be helpful to also see: total # of messages/docs.

Extracted from #322


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `securedrop/db.py`
Content:
```
1 import os
2 import datetime
3 
4 from sqlalchemy import create_engine, ForeignKey
5 from sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref
6 from sqlalchemy.ext.declarative import declarative_base
7 from sqlalchemy import Column, Integer, String, Boolean, DateTime
8 from sqlalchemy.orm.exc import NoResultFound
9 
10 import config
11 import crypto_util
12 import store
13 
14 # http://flask.pocoo.org/docs/patterns/sqlalchemy/
15 
16 if config.DATABASE_ENGINE == "sqlite":
17     engine = create_engine(
18         config.DATABASE_ENGINE + ":///" +
19         config.DATABASE_FILE
20     )
21 else:
22     engine = create_engine(
23         config.DATABASE_ENGINE + '://' +
24         config.DATABASE_USERNAME + ':' +
25         config.DATABASE_PASSWORD + '@' +
26         config.DATABASE_HOST + '/' +
27         config.DATABASE_NAME, echo=False
28     )
29 
30 db_session = scoped_session(sessionmaker(autocommit=False,
31                                          autoflush=False,
32                                          bind=engine))
33 Base = declarative_base()
34 Base.query = db_session.query_property()
35 
36 
37 class Source(Base):
38     __tablename__ = 'sources'
39     id = Column(Integer, primary_key=True)
40     filesystem_id = Column(String(96), unique=True)
41     journalist_designation = Column(String(255), nullable=False)
42     flagged = Column(Boolean, default=False)
43     last_updated = Column(DateTime, default=datetime.datetime.now)
44     
45     # sources are "pending" and don't get displayed to journalists until they submit something
46     pending = Column(Boolean, default=True)
47 
48     # keep track of how many interactions have happened, for filenames
49     interaction_count = Column(Integer, default=0, nullable=False)
50 
51     def __init__(self, filesystem_id=None, journalist_designation=None):
52         self.filesystem_id = filesystem_id
53         self.journalist_designation = journalist_designation
54 
55     def __repr__(self):
56         return '<Source %r>' % (self.journalist_designation)
57 
58     def journalist_filename(self):
59         valid_chars = 'abcdefghijklmnopqrstuvwxyz1234567890-_'
60         return ''.join([c for c in self.journalist_designation.lower().replace(' ', '_') if c in valid_chars])
61 
62 class Submission(Base):
63     __tablename__ = 'submissions'
64     id = Column(Integer, primary_key=True)
65     source_id = Column(Integer, ForeignKey('sources.id'))
66     source = relationship("Source", backref=backref('submissions', order_by=id))
67     filename = Column(String(255), nullable=False)
68     size = Column(Integer, nullable=False)
69 
70     def __init__(self, source, filename):
71         self.source_id = source.id
72         self.filename = filename
73         self.size = os.stat(store.path(source.filesystem_id, filename)).st_size
74 
75     def __repr__(self):
76         return '<Submission %r>' % (self.filename)
77 
78 
79 # Declare (or import) models before init_db
80 def init_db():
81     Base.metadata.create_all(bind=engine)
82 
83
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/securedrop/db.py b/securedrop/db.py
--- a/securedrop/db.py
+++ b/securedrop/db.py
@@ -59,6 +59,19 @@
         valid_chars = 'abcdefghijklmnopqrstuvwxyz1234567890-_'
         return ''.join([c for c in self.journalist_designation.lower().replace(' ', '_') if c in valid_chars])
 
+    def documents_messages_count(self):
+        try:
+            return self.docs_msgs_count
+        except AttributeError:
+            self.docs_msgs_count = {'messages': 0, 'documents': 0}
+            for submission in self.submissions:
+                if submission.filename.endswith('msg.gpg'):
+                    self.docs_msgs_count['messages'] += 1
+                elif submission.filename.endswith('doc.zip.gpg'):
+                    self.docs_msgs_count['documents'] += 1
+            return self.docs_msgs_count
+
+
 class Submission(Base):
     __tablename__ = 'submissions'
     id = Column(Integer, primary_key=True)

{"golden_diff": "diff --git a/securedrop/db.py b/securedrop/db.py\n--- a/securedrop/db.py\n+++ b/securedrop/db.py\n@@ -59,6 +59,19 @@\n         valid_chars = 'abcdefghijklmnopqrstuvwxyz1234567890-_'\n         return ''.join([c for c in self.journalist_designation.lower().replace(' ', '_') if c in valid_chars])\n \n+    def documents_messages_count(self):\n+        try:\n+            return self.docs_msgs_count\n+        except AttributeError:\n+            self.docs_msgs_count = {'messages': 0, 'documents': 0}\n+            for submission in self.submissions:\n+                if submission.filename.endswith('msg.gpg'):\n+                    self.docs_msgs_count['messages'] += 1\n+                elif submission.filename.endswith('doc.zip.gpg'):\n+                    self.docs_msgs_count['documents'] += 1\n+            return self.docs_msgs_count\n+\n+\n class Submission(Base):\n     __tablename__ = 'submissions'\n     id = Column(Integer, primary_key=True)\n", "issue": "Display number of docs and messages per source in source list\n> At the moment each source in the list displays: source codename, last updated. It would be helpful to also see: total # of messages/docs.\n\nExtracted from #322\n\n", "before_files": [{"content": "import os\nimport datetime\n\nfrom sqlalchemy import create_engine, ForeignKey\nfrom sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy import Column, Integer, String, Boolean, DateTime\nfrom sqlalchemy.orm.exc import NoResultFound\n\nimport config\nimport crypto_util\nimport store\n\n# http://flask.pocoo.org/docs/patterns/sqlalchemy/\n\nif config.DATABASE_ENGINE == \"sqlite\":\n    engine = create_engine(\n        config.DATABASE_ENGINE + \":///\" +\n        config.DATABASE_FILE\n    )\nelse:\n    engine = create_engine(\n        config.DATABASE_ENGINE + '://' +\n        config.DATABASE_USERNAME + ':' +\n        config.DATABASE_PASSWORD + '@' +\n        config.DATABASE_HOST + '/' +\n        config.DATABASE_NAME, echo=False\n    )\n\ndb_session = scoped_session(sessionmaker(autocommit=False,\n                                         autoflush=False,\n                                         bind=engine))\nBase = declarative_base()\nBase.query = db_session.query_property()\n\n\nclass Source(Base):\n    __tablename__ = 'sources'\n    id = Column(Integer, primary_key=True)\n    filesystem_id = Column(String(96), unique=True)\n    journalist_designation = Column(String(255), nullable=False)\n    flagged = Column(Boolean, default=False)\n    last_updated = Column(DateTime, default=datetime.datetime.now)\n    \n    # sources are \"pending\" and don't get displayed to journalists until they submit something\n    pending = Column(Boolean, default=True)\n\n    # keep track of how many interactions have happened, for filenames\n    interaction_count = Column(Integer, default=0, nullable=False)\n\n    def __init__(self, filesystem_id=None, journalist_designation=None):\n        self.filesystem_id = filesystem_id\n        self.journalist_designation = journalist_designation\n\n    def __repr__(self):\n        return '<Source %r>' % (self.journalist_designation)\n\n    def journalist_filename(self):\n        valid_chars = 'abcdefghijklmnopqrstuvwxyz1234567890-_'\n        return ''.join([c for c in self.journalist_designation.lower().replace(' ', '_') if c in valid_chars])\n\nclass Submission(Base):\n    __tablename__ = 'submissions'\n    id = Column(Integer, primary_key=True)\n    source_id = Column(Integer, ForeignKey('sources.id'))\n    source = relationship(\"Source\", backref=backref('submissions', order_by=id))\n    filename = Column(String(255), nullable=False)\n    size = Column(Integer, nullable=False)\n\n    def __init__(self, source, filename):\n        self.source_id = source.id\n        self.filename = filename\n        self.size = os.stat(store.path(source.filesystem_id, filename)).st_size\n\n    def __repr__(self):\n        return '<Submission %r>' % (self.filename)\n\n\n# Declare (or import) models before init_db\ndef init_db():\n    Base.metadata.create_all(bind=engine)\n\n", "path": "securedrop/db.py"}], "after_files": [{"content": "import os\nimport datetime\n\nfrom sqlalchemy import create_engine, ForeignKey\nfrom sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy import Column, Integer, String, Boolean, DateTime\nfrom sqlalchemy.orm.exc import NoResultFound\n\nimport config\nimport crypto_util\nimport store\n\n# http://flask.pocoo.org/docs/patterns/sqlalchemy/\n\nif config.DATABASE_ENGINE == \"sqlite\":\n    engine = create_engine(\n        config.DATABASE_ENGINE + \":///\" +\n        config.DATABASE_FILE\n    )\nelse:\n    engine = create_engine(\n        config.DATABASE_ENGINE + '://' +\n        config.DATABASE_USERNAME + ':' +\n        config.DATABASE_PASSWORD + '@' +\n        config.DATABASE_HOST + '/' +\n        config.DATABASE_NAME, echo=False\n    )\n\ndb_session = scoped_session(sessionmaker(autocommit=False,\n                                         autoflush=False,\n                                         bind=engine))\nBase = declarative_base()\nBase.query = db_session.query_property()\n\n\nclass Source(Base):\n    __tablename__ = 'sources'\n    id = Column(Integer, primary_key=True)\n    filesystem_id = Column(String(96), unique=True)\n    journalist_designation = Column(String(255), nullable=False)\n    flagged = Column(Boolean, default=False)\n    last_updated = Column(DateTime, default=datetime.datetime.now)\n    \n    # sources are \"pending\" and don't get displayed to journalists until they submit something\n    pending = Column(Boolean, default=True)\n\n    # keep track of how many interactions have happened, for filenames\n    interaction_count = Column(Integer, default=0, nullable=False)\n\n    def __init__(self, filesystem_id=None, journalist_designation=None):\n        self.filesystem_id = filesystem_id\n        self.journalist_designation = journalist_designation\n\n    def __repr__(self):\n        return '<Source %r>' % (self.journalist_designation)\n\n    def journalist_filename(self):\n        valid_chars = 'abcdefghijklmnopqrstuvwxyz1234567890-_'\n        return ''.join([c for c in self.journalist_designation.lower().replace(' ', '_') if c in valid_chars])\n\n    def documents_messages_count(self):\n        try:\n            return self.docs_msgs_count\n        except AttributeError:\n            self.docs_msgs_count = {'messages': 0, 'documents': 0}\n            for submission in self.submissions:\n                if submission.filename.endswith('msg.gpg'):\n                    self.docs_msgs_count['messages'] += 1\n                elif submission.filename.endswith('doc.zip.gpg'):\n                    self.docs_msgs_count['documents'] += 1\n            return self.docs_msgs_count\n\n\nclass Submission(Base):\n    __tablename__ = 'submissions'\n    id = Column(Integer, primary_key=True)\n    source_id = Column(Integer, ForeignKey('sources.id'))\n    source = relationship(\"Source\", backref=backref('submissions', order_by=id))\n    filename = Column(String(255), nullable=False)\n    size = Column(Integer, nullable=False)\n\n    def __init__(self, source, filename):\n        self.source_id = source.id\n        self.filename = filename\n        self.size = os.stat(store.path(source.filesystem_id, filename)).st_size\n\n    def __repr__(self):\n        return '<Submission %r>' % (self.filename)\n\n\n# Declare (or import) models before init_db\ndef init_db():\n    Base.metadata.create_all(bind=engine)\n\n", "path": "securedrop/db.py"}]}