Merge lp:~jderose/dmedia/project-scan into lp:dmedia

Proposed by Jason Gerard DeRose
Status: Merged
Merged at revision: 444
Proposed branch: lp:~jderose/dmedia/project-scan
Merge into: lp:dmedia
Diff against target: 161 lines (+83/-4)
4 files modified
dmedia/core.py (+26/-3)
dmedia/schema.py (+26/-0)
dmedia/tests/test_core.py (+15/-1)
dmedia/tests/test_schema.py (+16/-0)
To merge this branch: bzr merge lp:~jderose/dmedia/project-scan
Reviewer Review Type Date Requested Status
David Jordan Approve
Review via email: mp+119303@code.launchpad.net

Description of the change

* Adds schema.get_project_id() function (and test) to go from dmedia-0-project_id to PROJECT_ID

* Adds core.projects_iter() function (and test) to iterate through all Dmedia project databases

* Changes Core.init_project_views() to use projects_iter() instead of the project/atime view, and to copy over the project doc into dmedia-0 when it doesn't already exist

To post a comment you must log in.
lp:~jderose/dmedia/project-scan updated
448. By Jason Gerard DeRose

Core.init_project_views() now preps project/atime view for performance reasons

Revision history for this message
David Jordan (dmj726) wrote :

Approved!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dmedia/core.py'
2--- dmedia/core.py 2012-08-06 11:03:16 +0000
3+++ dmedia/core.py 2012-08-13 06:09:20 +0000
4@@ -38,7 +38,7 @@
5 import logging
6 from queue import Queue
7
8-from microfiber import Database, NotFound, Conflict, random_id2
9+from microfiber import Server, Database, NotFound, Conflict
10 from filestore import FileStore, check_root_hash, check_id, _start_thread
11
12 import dmedia
13@@ -83,6 +83,17 @@
14 return (httpd, port)
15
16
17+def projects_iter(env):
18+ server = Server(env)
19+ for name in server.get('_all_dbs'):
20+ if name.startswith('_'):
21+ continue
22+ _id = schema.get_project_id(name)
23+ if _id is None:
24+ continue
25+ yield (name, _id)
26+
27+
28 class Core:
29 def __init__(self, env, private=None, shared=None, full_init=True):
30 self.env = env
31@@ -172,8 +183,20 @@
32 self.thread = _start_thread(self._background_worker)
33
34 def init_project_views(self):
35- for row in self.db.view('project', 'atime')['rows']:
36- util.get_project_db(row['id'], self.env, True)
37+ try:
38+ for (name, _id) in projects_iter(self.env):
39+ db = util.get_project_db(_id, self.env, True)
40+ try:
41+ doc = self.db.get(_id)
42+ except NotFound:
43+ log.info('missing project doc for %s', _id)
44+ doc = db.get(_id)
45+ del doc['_rev']
46+ self.db.save(doc)
47+ except Exception:
48+ log.exception('Error in Core.init_project_views():')
49+ log.info('prepping project/atime view...')
50+ self.db.view('project', 'atime')
51 log.info('Core.init_project_views() complete')
52
53 def set_default_store(self, value):
54
55=== modified file 'dmedia/schema.py'
56--- dmedia/schema.py 2012-08-06 11:27:03 +0000
57+++ dmedia/schema.py 2012-08-13 06:09:20 +0000
58@@ -259,6 +259,9 @@
59 # Pattern that doc['ext'] must match for dmedia/file
60 EXT_PAT = '^[a-z0-9]+(\.[a-z0-9]+)?$'
61
62+# Pattern to match a project DB name
63+PROJECT_DB_PAT = '^dmedia-0-([234567abcdefghijklmnopqrstuvwxyz]{24})$'
64+
65
66 # Some private helper functions that don't directly define any schema.
67 #
68@@ -984,10 +987,33 @@
69 >>> project_db_name('HB6YSCKAY27KIWUTWKGKCTNI')
70 'dmedia-0-hb6ysckay27kiwutwkgkctni'
71
72+ Also see `get_project_id()`.
73 """
74 return '-'.join(['dmedia', str(VER), _id.lower()])
75
76
77+def get_project_id(db_name):
78+ """
79+ Return project ID from CouchDB database name.
80+
81+ For example:
82+
83+ >>> get_project_id('dmedia-0-hb6ysckay27kiwutwkgkctni')
84+ 'HB6YSCKAY27KIWUTWKGKCTNI'
85+
86+ If *db_name* doesn't match the expected naming convention, ``None`` is
87+ returned:
88+
89+ >>> get_project_id('dmedia-hb6ysckay27kiwutwkgkctni') is None
90+ True
91+
92+ Also see `project_db_name()`.
93+ """
94+ match = re.match(PROJECT_DB_PAT, db_name)
95+ if match:
96+ return match.group(1).upper()
97+
98+
99 def create_project(title=''):
100 _id = random_id()
101 ts = time.time()
102
103=== modified file 'dmedia/tests/test_core.py'
104--- dmedia/tests/test_core.py 2012-07-21 00:23:37 +0000
105+++ dmedia/tests/test_core.py 2012-08-13 06:09:20 +0000
106@@ -32,13 +32,27 @@
107 import filestore
108
109 from dmedia.local import LocalStores
110-from dmedia.schema import DB_NAME, create_filestore
111+from dmedia.schema import DB_NAME, create_filestore, project_db_name
112 from dmedia import util, core
113
114 from .couch import CouchCase
115 from .base import TempDir
116
117
118+class TestCouchFunctions(CouchCase):
119+ def test_projects_iter(self):
120+ self.assertEqual(list(core.projects_iter(self.env)), [])
121+ ids = tuple(random_id() for i in range(20))
122+ server = microfiber.Server(self.env)
123+ for _id in ids:
124+ db_name = project_db_name(_id)
125+ server.put(None, db_name)
126+ self.assertEqual(
127+ list(core.projects_iter(self.env)),
128+ [(project_db_name(_id), _id) for _id in sorted(ids)]
129+ )
130+
131+
132 class TestCore(CouchCase):
133 def test_init(self):
134 inst = core.Core(self.env)
135
136=== modified file 'dmedia/tests/test_schema.py'
137--- dmedia/tests/test_schema.py 2012-08-06 11:27:03 +0000
138+++ dmedia/tests/test_schema.py 2012-08-13 06:09:20 +0000
139@@ -721,6 +721,22 @@
140 'dmedia-0-{}'.format(_id.lower())
141 )
142
143+ def test_get_project_id(self):
144+ self.assertEqual(
145+ schema.get_project_id('dmedia-0-aaaaaaaaaaaaaaaaaaaaaaaa'),
146+ 'AAAAAAAAAAAAAAAAAAAAAAAA'
147+ )
148+ self.assertIsNone(schema.get_project_id('dmedia-0'))
149+ self.assertIsNone(schema.get_project_id('novacut-0'))
150+ self.assertIsNone(
151+ schema.get_project_id('novacut-0-aaaaaaaaaaaaaaaaaaaaaaaa')
152+ )
153+ # Make sure we can round-trip with project_db_name():
154+ for i in range(1000):
155+ _id = random_id()
156+ db_name = schema.project_db_name(_id)
157+ self.assertEqual(schema.get_project_id(db_name), _id)
158+
159 def test_create_project(self):
160 doc = schema.create_project()
161 schema.check_project(doc)

Subscribers

People subscribed via source and target branches