summaryrefslogtreecommitdiff
path: root/project1/proj1_s4498062/webhttp/resource.py
blob: ee05fa7fdd939b3e1498ec33835f70b6d8f41eca (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
"""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)