summaryrefslogblamecommitdiff
path: root/project1/proj1_s4498062/webhttp/resource.py
blob: 9509f823d4ff665acf93883e85d9153c9c4ab6a4 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                                    
                
            
               
                 
          
                
                
                          
                 
                    
 
 





















                                                                             
                                 
                                     
                                                                     
                                          
                                     
                                                           
                                              










                                              

                                            
                    





                                                                             
                                                        



                                            
                                                   
























                                                   
"""Resources

This module contains a handler class for resources.
"""

import binascii
import gzip
import hashlib
import mimetypes
import os
import re
import StringIO
import urlparse

from config import config
import encodings
import regexes as r


class FileExistError(Exception):
    """Exception which is raised when file does not exist"""
    pass


class FileAccessError(Exception):
    """Exception which is raised when file exists, but cannot be accessed"""
    pass


class Resource:
    """Class for representing a Resource (file)"""

    def __init__(self, uri):
        """Initialize the resource"

        Raises:
            FileExistError: if resource does not exist
            FileAccessError: if resource exists, but cannot be accessed

        Args:
            uri (str): Uniform Resource Identifier
        """
        if uri == None:
            raise FileExistError
        self.uri = uri
        out = urlparse.urlparse(uri)
        self.path = os.path.join(config('root', default='content'), 
                out.path.lstrip("/"))
        if not os.path.exists(self.path):
            raise FileExistError
        if os.path.isdir(self.path):
            self.path = os.path.join(self.path, 
                    config('index', default='index.html'))
            if not os.path.exists(self.path):
                raise FileAccessError
        if not os.path.isfile(self.path):
            raise FileExistError
        if not os.access(self.path, os.R_OK):
            raise FileAccessError

    def generate_etag(self):
        """Generate the ETag for the resource

        Returns:
            str: ETag for the resource
        """
        stat = os.stat(self.path)
        m = hashlib.md5()
        m.update(str(stat))
        etag = binascii.hexlify(m.digest())
        return etag

    def etag_match(self, etag):
        if etag == None:
            return False
        my_etag = self.generate_etag()
        return etag == '*' or \
                any([tag == my_etag for tag in re.split(r.ETagSplit, etag)])

    def get_content(self, encoding=encodings.IDENTITY):
        """Get the contents of the resource
        
        Returns:
            str: Contents of the resource
        """
        content = open(self.path).read()
        return encodings.encode(encoding, content)

    def get_content_type(self):
        """Get the content type, i.e "text/html"

        Returns:
            str: type of content in the resource
        """
        mimetype = mimetypes.guess_type(self.path)
        return mimetype[0]

    def get_content_encoding(self):
        """Get the content encoding, i.e "gzip"

        Returns:
            str: encoding used for the resource
        """
        mimetype = mimetypes.guess_type(self.path)
        return mimetype[1]

    def get_content_length(self):
        """Get the length of the resource

        Returns:
            int: length of resource in bytes
        """
        return os.path.getsize(self.path)