def putFile(request, dict, thumbnail=False, do_delete=False, temporary=False, ticket=None, permanent=False): """ Puts the file (found in dict) into the database. dict is a dictionary with possible keys: filename, filecontent, uploaded_time, uploaded_by, pagename, uploaded_by_ip, xsize, ysize, deleted_time, deleted_by, deleted_by_ip. """ from Sycamore.wikiutil import mc_quote, isImage from Sycamore.Page import Page from Sycamore import caching from Sycamore.action.Files import get_filedict def set_cache_for_file(): """ Sets the memory cache for the new file. """ if not config.memcache: return if not do_delete: if not thumbnail: table = 'files' else: table = 'thumbnails' if not temporary: key = "%s:%s,%s" % (table, mc_quote(dict['filename']), mc_quote(dict['pagename'].lower())) else: key = "%s,%s,%s" % (table, mc_quote(dict['filename']), ticket) image_obj = (raw_image, uploaded_time) request.mc.set(key, image_obj) else: if not thumbnail: key = "files:%s,%s" % (mc_quote(dict['filename']), mc_quote(dict['pagename'].lower())) request.mc.set(key, False) if is_image and thumbnail: key = "thumbnails:%s,%s" % (mc_quote(dict['filename']), mc_quote(dict['pagename'].lower())) request.mc.set(key, False) # set new file dict if not replaced_image: get_filedict(request, dict['pagename'], fresh=True, set=True) def rebuild_page_cache(): """ Rebuilds the page cache. """ if not request.generating_cache and not request.previewing_page: from Sycamore import caching from Sycamore.Page import Page page = Page(dict['pagename'], request) if page.exists(): page.buildCache() def handle_file_add(): request.cursor.execute( """SELECT name from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict) exists = request.cursor.fetchone() if exists: # backup file, then remove it replaced_image = True request.cursor.execute( """INSERT into oldFiles (name, file, uploaded_time, uploaded_by, attached_to_pagename, deleted_time, deleted_by, uploaded_by_ip, deleted_by_ip, attached_to_pagename_propercased, wiki_id) values (%(filename)s, (select file from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), (select uploaded_time from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), (select uploaded_by from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), %(pagename)s, %(uploaded_time)s, %(uploaded_by)s, (select uploaded_by_ip from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), %(uploaded_by_ip)s, %(pagename_propercased)s, %(wiki_id)s)""", dict, isWrite=True) if is_image: request.cursor.execute( """INSERT into oldImageInfo (name, attached_to_pagename, xsize, ysize, uploaded_time, wiki_id) values (%(filename)s, %(pagename)s, (select xsize from imageInfo where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), (select ysize from imageInfo where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), (select uploaded_time from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), %(wiki_id)s)""", dict, isWrite=True) request.cursor.execute( """DELETE from imageInfo where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict, isWrite=True) request.cursor.execute( """DELETE from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict, isWrite=True) request.cursor.execute( """INSERT into files (name, file, uploaded_time, uploaded_by, attached_to_pagename, uploaded_by_ip, attached_to_pagename_propercased, wiki_id) values (%(filename)s, %(filecontent)s, %(uploaded_time)s, %(uploaded_by)s, %(pagename)s, %(uploaded_by_ip)s, %(pagename_propercased)s, %(wiki_id)s)""", dict, isWrite=True) if is_image: request.cursor.execute( """INSERT into imageInfo (name, attached_to_pagename, xsize, ysize, wiki_id) values (%(filename)s, %(pagename)s, %(xsize)s, %(ysize)s, %(wiki_id)s)""", dict, isWrite=True) caching.updateRecentChanges(page) def handle_thumbnail_add(): request.cursor.execute( """SELECT name from thumbnails where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict) exists = request.cursor.fetchone() if exists: request.cursor.execute( """UPDATE thumbnails set xsize=%(x)s, ysize=%(y)s, image=%(filecontent)s, last_modified=%(uploaded_time)s where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict, isWrite=True) else: request.cursor.execute( """INSERT into thumbnails (xsize, ysize, name, image, last_modified, attached_to_pagename, wiki_id) values (%(x)s, %(y)s, %(filename)s, %(filecontent)s, %(uploaded_time)s, %(pagename)s, %(wiki_id)s)""", dict, isWrite=True) def handle_file_delete(): request.cursor.execute( """SELECT name from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict) has_file = request.cursor.fetchone() if has_file: if not permanent: # backup file request.cursor.execute(""" INSERT into oldFiles (name, attached_to_pagename, file, uploaded_by, uploaded_time, deleted_time, deleted_by, uploaded_by_ip, deleted_by_ip, attached_to_pagename_propercased, wiki_id) values (%(filename)s, %(pagename)s, (select file from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), (select uploaded_by from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), (select uploaded_time from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), %(deleted_time)s, %(deleted_by)s, (select uploaded_by_ip from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), %(deleted_by_ip)s, (select attached_to_pagename_propercased from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), %(wiki_id)s)""", dict, isWrite=True) else: # nuke all old cached versions of the file caching.deleteAllFileInfo(dict['filename'], dict['pagename'], request) # nuke all old versions request.cursor.execute( """DELETE from oldFiles where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict, isWrite=True) if is_image: if not permanent: # backup image info request.cursor.execute( """INSERT into oldImageInfo (name, attached_to_pagename, xsize, ysize, uploaded_time, wiki_id) values (%(filename)s, %(pagename)s, (select xsize from imageInfo where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), (select ysize from imageInfo where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), (select uploaded_time from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s ), %(wiki_id)s)""", dict, isWrite=True) else: # nuke all old versions request.cursor.execute( """DELETE from oldImageInfo where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict, isWrite=True) # delete image info request.cursor.execute( """DELETE from imageInfo where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict, isWrite=True) # delete file request.cursor.execute( """DELETE from files where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict, isWrite=True) caching.updateRecentChanges(page) def handle_thumbnail_delete(): """ delete thumbnail. """ request.cursor.execute( """DELETE from thumbnails where name=%(filename)s and attached_to_pagename=%(pagename)s and wiki_id=%(wiki_id)s""", dict, isWrite=True) # prep for insert of binary data if dict.has_key('filecontent'): raw_image = dict['filecontent'] uploaded_time = dict['uploaded_time'] dict['filecontent'] = dbapi.Binary(raw_image) page = Page(dict['pagename'], request) dict['pagename_propercased'] = page.proper_name() dict['pagename'] = dict['pagename'].lower() dict['wiki_id'] = request.config.wiki_id replaced_image = False is_image = isImage(dict['filename']) if temporary: # we don't update the database in this case set_cache_for_file() rebuild_page_cache() return if not thumbnail and not do_delete: handle_file_add() elif thumbnail and not do_delete: handle_thumbnail_add() elif do_delete: if not thumbnail: handle_file_delete() else: handle_thumbnail_delete() set_cache_for_file() rebuild_page_cache()
def getFile(request, dict, deleted=False, thumbnail=False, version=0, ticket=None, size=None, fresh=False): """ Get the file from the database. @param dict: a dictionary with possible keys: filename, page_name, and file_version. @param deleted: whether or not the version of the file we want is a deleted version. @param thumbnail: whether or not the file is an image thumbnail. @param version: he unix timestamp of the version of the file we want. Leave blank for the current version. @param ticket: request ticket that we need to avoid thumbnail regeneration. Only applies for thumbnails. @param size: the integer size of the image we are grabbing. Only applies for images. @param fresh: if True then grab only fresh data -- nothing stale from the cache. @return: either False if the file doesn't exist, or a tuple: (filecontentstring, last_modified_date) """ def assemble_query(): from Sycamore.wikiutil import mc_quote # let's assemble the query and key if we use memcache key = None query = '' if not deleted and not thumbnail and not version: if config.memcache: key = "files:%s,%s" % (mc_quote(dict['filename']), mc_quote(dict['page_name'])) query = """SELECT file, uploaded_time from files where name=%(filename)s and attached_to_pagename=%(page_name)s and wiki_id=%(wiki_id)s""" elif thumbnail: if not ticket: if config.memcache: key = "thumbnails:%s,%s" % (mc_quote(dict['filename']), mc_quote(dict['page_name'])) query = """SELECT image, last_modified from thumbnails where name=%(filename)s and attached_to_pagename=%(page_name)s and wiki_id=%(wiki_id)s""" else: if config.memcache: size_encoded, ticket_encoded = size, ticket if size: size_encoded = size.encode(config.charset) if ticket: ticket_encoded = ticket.encode(config.charset) key = "thumbnails:%s,%s" % (mc_quote(dict['filename']), size_encoded or ticket_encoded) elif deleted: # default behavior is to grab the latest backup # version of the image if not version: if config.memcache: key = "oldfiles:%s,%s" % (mc_quote(dict['filename']), mc_quote(dict['page_name'])) query = """SELECT file, uploaded_time from oldFiles where name=%(filename)s and attached_to_pagename=%(page_name)s and wiki_id=%(wiki_id)s order by uploaded_time desc;""" elif version: if config.memcache: key = "oldfiles:%s,%s,%s" % (mc_quote(dict['filename']), mc_quote(dict['page_name']), version) query = """SELECT file, uploaded_time from oldFiles where name=%(filename)s and attached_to_pagename=%(page_name)s and uploaded_time=%(file_version)s and wiki_id=%(wiki_id)s""" return query, key file_obj = None dict['page_name'] = dict['page_name'].lower() dict['wiki_id'] = request.config.wiki_id query, key = assemble_query() if config.memcache and key and not fresh: file_obj = request.mc.get(key) if file_obj is None: from wikiutil import isImage if ticket and isImage(dict['filename']): # we generate the thumbnail..weee from Sycamore.macro import image file_obj = (image.generateThumbnail(request, dict['page_name'], dict['filename'], dict['maxsize'], return_image=True), 0) else: request.cursor.execute(query, dict) file_obj = request.cursor.fetchone() if not file_obj: # False so that we know it's not there when we check the mc file_obj = False else: # Messy because of a bug in python for pickling # array.array -- must convert to str before putting in memcache new_file_obj = (binaryToString(file_obj[0]), file_obj[1]) file_obj = new_file_obj if config.memcache: request.mc.add(key, file_obj) if file_obj: return file_obj[0], float(file_obj[1])