Ejemplo n.º 1
0
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()
Ejemplo n.º 2
0
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])