Thanks Anthony. As it turned out I also needed to add db.file.type to my path so this worked a treat.
I'll have a play with the retrieve function. Cheers On Tuesday, April 9, 2013 11:47:59 PM UTC+12, Anthony wrote: > > Another option -- when submitting a form, the value for db.file.client > should be in request.vars.client, so you could do: > > custom_store=lambda file, filename, path: store_file(file, filename, path, > db.client(request.vars.client).client_dir_name if request.vars.client > else None) > > You will also need to fetch the client id in custom_retrieve, though that > will be trickier because it won't be in request.vars in that case. Instead, > I would recommend you include the custom directory name within the filename > created by custom_store -- so custom_store would create a filename like > table.field.folder.uuid_fragment.encoded_filename.ext. Then your > custom_retrieve function could simply extract the directory name from the > filename. In fact, in that case, you don't need an entire custom_retrieve > function -- instead, you can just implement a > custom_retrieve_file_properties function (see > https://code.google.com/p/web2py/source/browse/gluon/dal.py#9355 for what > that function is supposed to return). That way, when retrieving the file, > you don't need the client id, and you avoid an unnecessary database query > to get the directory name (which is already available in the filename). > > Anthony > > On Monday, April 8, 2013 11:26:09 PM UTC-4, James Burke wrote: >> >> Came up with a workaround. >> def store_file(file, filename=None, path=None): >> try: >> client_id = int(request.args[2]) >> client_dir = db(db.client.id == client_id).select(db.client. >> client_dir_name).first().client_dir_name >> except: >> client_dir = 'Default' >> >> path = "applications/init/uploads/%s" % (client_dir) >> if not os.path.exists(path): >> os.makedirs(path) >> pathfilename = os.path.join(path, filename) >> dest_file = open(pathfilename, 'wb') >> try: >> shutil.copyfileobj(file, dest_file) >> finally: >> dest_file.close() >> >> >> return filename >> >> I'm using a smartgrid so the client id is passed as an argument when I >> client on the files link. >> >> On Tuesday, April 9, 2013 2:34:35 PM UTC+12, James Burke wrote: >>> >>> Thanks for your swift response. >>> >>> I kind of understand that, but how do you get the value rather than the >>> field name? >>> >>> db.define_table('file', >>> Field('client', 'reference client'), >>> Field('type', requires=IS_IN_SET(['Clipper','Workbench', 'Terramatch', >>> 'Supply']), default='Workbench'), >>> Field('file', type='upload', >>> custom_store=lambda file,filename,path: store_file(file, filename, path >>> , db.file.client._id), >>> custom_retrieve=lambda filename, path: retrieve_file(filename, path, db >>> .file.client)), >>> format='%(file)s') >>> >>> I'm trying to retrieve the clients name and use it to generate the >>> folder. >>> >>> Cheers, >>> >>> -James >>> >>> >>> On Tuesday, April 9, 2013 2:06:54 PM UTC+12, Anthony wrote: >>>> >>>> The fourth argument passed to store_file() is db.table.new_filename, >>>> which is a DAL Field object. Your code is treating it as a string, and >>>> "table.new_filename" is the string representation of a Field object. If >>>> you >>>> want to include an actual filename string, then that's what you have to >>>> pass to the function. >>>> >>>> Anthony >>>> >>>> On Monday, April 8, 2013 9:34:45 PM UTC-4, James Burke wrote: >>>>> >>>>> Hi Anthony, >>>>> >>>>> I've tried the solution you've posted below: >>>>> Field('file', 'upload', >>>>> custom_store=lambda file, filename, path: store_file(file,filename >>>>> , path, db.table.new_filename), >>>>> ...) >>>>> >>>>> But when my additional parameter gets sent to store_file it sends >>>>> 'table.new_filename' >>>>> >>>>> def store_file(file, filename=None, path=None, new_filename=None): >>>>> path = "applications/init/uploads/%s" % (new_filename) >>>>> if not os.path.exists(path): >>>>> os.makedirs(path) >>>>> pathfilename = os.path.join(path, filename) >>>>> dest_file = open(pathfilename, 'wb') >>>>> try: >>>>> shutil.copyfileobj(file, dest_file) >>>>> finally: >>>>> dest_file.close() >>>>> >>>>> >>>>> return filename >>>>> >>>>> Results in a new folder in uploads called 'table.new_filename' >>>>> >>>>> Cheers >>>>> -James >>>>> >>>>> On Wednesday, August 8, 2012 11:51:44 PM UTC+12, Anthony wrote: >>>>>> >>>>>> On Wednesday, August 8, 2012 7:09:37 AM UTC-4, Jim Gregory wrote: >>>>>>> >>>>>>> Can custom_store and custom_retrieve take parameters when they are >>>>>>> called using Field, e.g.: >>>>>>> db.define_table('table', >>>>>>> Field('file', 'upload', custom_store=store_file(file, >>>>>>> db.table.new_filename), >>>>>>> custom_retrieve=retrieve_file(db.table.new_filename))? >>>>>>> Field('new_filename','string') >>>>>>> ) >>>>>>> >>>>>> >>>>>> These attributes have to be callables, so you can't call them >>>>>> yourself. To pass additional custom arguments to a callable, just turn >>>>>> it >>>>>> into a lambda that takes the standard arguments and pass the additional >>>>>> arguments to your function within the lambda: >>>>>> >>>>>> Field('file', 'upload', >>>>>> custom_store=lambda file, filename, path: store_file(file,filename >>>>>> , path, db.table.new_filename), >>>>>> ...) >>>>>> >>>>>> When web2py calls the custom_store callable, it will pass three >>>>>> arguments (file, filename, and path), so your lambda must take three >>>>>> arguments. Within the lambda, you can then do whatever you want. You can >>>>>> pass any or all of the standard three arguments to your custom function, >>>>>> and you can pass additional arguments. In the example above, I passed >>>>>> the >>>>>> three standard arguments followed by a fourth custom argument, though it >>>>>> doesn't have to look like that (presumably you will at least want to >>>>>> pass >>>>>> the file as an argument). >>>>>> >>>>>> custom_retrieve takes two standard arguments, "name" and "path". >>>>>> >>>>>> Anthony >>>>>> >>>>>> -- --- You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.