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.


Reply via email to