Skip to content

Commit 740c4ed

Browse files
committed
Update utilities to upload programs in bulk
1 parent 5e82581 commit 740c4ed

3 files changed

Lines changed: 78 additions & 10 deletions

File tree

fs_utils.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""
2+
These are filesytem based utilities to help with housekeeping.
3+
"""
4+
5+
import os
6+
7+
def LoadPrograms(**kwargs):
8+
"""
9+
Iterate through the python programs in a folder.
10+
"""
11+
path = kwargs['path']
12+
for file in os.listdir(path):
13+
if file.endswith(".py"):
14+
with open(os.path.join(path, file)) as f:
15+
code = f.read()
16+
yield file, code
17+
18+
def LoadProgramVisitor(path, func):
19+
for pname, code in LoadPrograms(path=path):
20+
func(pname, code)
21+
22+
def buildLoader(client, Program, ndb, user_id, folder_id, modDBFunctions):
23+
24+
def loader(pname, code):
25+
code = code.replace('from vpython import *', 'Web VPython 3.2\n')
26+
modDBFunctions.SetProgramSource(ndb, Program, user_id, folder_id, pname, code)
27+
28+
wrapped_loader = modDBFunctions.with_context(client)(loader)
29+
30+
return wrapped_loader
31+
32+
if __name__ == '__main__':
33+
LoadProgramVisitor(path='/Users/steve/Development/instructormi/assets/lecture-demo-programs/PUBLIC', func=lambda pname, code: print(pname))

ide/modDBFunctions.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
#
22
# These are some functions that could be usefult to fiddle with the Datastore entities moving from python2 to python3
33

4+
import functools
5+
6+
def with_context(client):
7+
"""
8+
Set up an ndb client context to call ndb functions
9+
"""
10+
def decorator(func):
11+
@functools.wraps(func) # Preserves original function's metadata
12+
def wrapper(*args, **kwargs):
13+
with client.context():
14+
return func(*args, **kwargs)
15+
return wrapper
16+
return decorator
17+
418
def NewUser(**kwargs):
519
"""
620
Create a fake user with a gaeUser entity but no email address
@@ -46,6 +60,24 @@ def DumpUsers(**kwargs):
4660
for s in kwargs['User'].query():
4761
print (s)
4862

63+
def ListFolders(ndb, user_id, Folder):
64+
65+
ancestor_key = ndb.Key('User', user_id)
66+
67+
for f in Folder.query(ancestor=ancestor_key):
68+
print (f)
69+
70+
def SetProgramSource(ndb, Program, user_id, folder_id, program_name, code):
71+
program_key = ndb.Key('User', user_id, 'Folder', folder_id, 'Program', program_name)
72+
ancestor_key = ndb.Key('User', user_id, 'Folder', folder_id)
73+
74+
program_object = program_key.get()
75+
76+
if not program_object:
77+
program_object = Program(parent=ancestor_key, id=program_name)
78+
79+
program_object.source = code
80+
program_object.put()
4981

5082
def SetSetting(name, value, **kwargs):
5183
Setting = kwargs['Setting']

main.py

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
from ide import app, models, routes, modDBFunctions
33
from google.cloud import ndb
44

5-
65
@app.shell_context_processor
76
def make_shell_context():
87
"""
9-
In the flask shell use the `wc` function to call ndb methods like so:
8+
In the flask shell use the `wc` decorator to call ndb methods like so:
9+
10+
@wc
11+
def doSomething(foo, bar):
12+
modDBFunctions.DumpUsers(User=foo, Bar=bar)
1013
11-
`wc(modDBFunction.DumpUsers, User=User)`
14+
doSomething()
1215
1316
This will create an ndb context and then invoke the requested function with kwargs provided.
1417
@@ -18,12 +21,12 @@ def make_shell_context():
1821

1922
client = ndb.Client(project=project) # for user data, folders, and programs
2023

21-
def wc(func, **args):
22-
with client.context():
23-
func(**args)
24-
25-
return {'app': app, 'User': models.User, 'Folder':models.Folder, 'Program':models.Program, 'Setting':models.Setting,
26-
'ndb':ndb, 'wc':wc, 'models':models, 'routes':routes,
27-
'project':project, 'client':client, 'modDBFunctions':modDBFunctions}
24+
import fs_utils as fsu
2825

26+
def doLoadPrograms(path):
27+
loader = fsu.buildLoader(client, models.Program, ndb, 'localuser', 'testupdate', modDBFunctions)
28+
fsu.LoadProgramVisitor(path, loader)
2929

30+
return {'app': app, 'User': models.User, 'Folder':models.Folder, 'Program':models.Program,
31+
'Setting':models.Setting,'ndb':ndb, 'models':models, 'routes':routes, 'project':project,
32+
'client':client, 'modDBFunctions':modDBFunctions, 'doLoadPrograms':doLoadPrograms}

0 commit comments

Comments
 (0)