-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathfactorymethod.py
115 lines (98 loc) · 3.45 KB
/
factorymethod.py
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
114
115
import abc #abstract base class
import urllib2
from BeautifulSoup import BeautifulStoneSoup
class Connector(object):
"""Abstract class to connect to remote resource"""
__metaclass__ = abc.ABCMeta #abstract class declaration
def __init__(self, is_secure):
self.is_secure = is_secure
self.port = self.port_factory_method()
self.protocol = self.protocol_factory_method()
@abc.abstractmethod
def parse(self):
"""Parse web content. Sould be defined in run time"""
pass
def read(self, host, path):
"""A generic method for all sublcalsses to read web conent"""
url = self.protocol + '://' + host + path
print 'Connecting to ', url
return urllib2.urlopen(url, timeout=2).read()
@abc.abstractmethod
def protocol_factory_method(self):
"""A factory method to be redefined in sublcass"""
pass
@abc.abstractmethod
def port_factory_method(self):
"""To be redefined in subclass"""
#return FTPPort()
pass
#let's create the concrete creators implementing the above abstract methods
#protocol_factory_method and port_factory_method
class HTTPConnector(Connector):
"""A concrete implemention of Conncetor to create http connector to set
attribut in runtime"""
def protocol_factory_method(self):
if self.is_secure:
return 'https'
return 'http'
def port_factory_method(self):
"""Here HTTPPort and HTTPSecurePort are concrete objects created by
factory method"""
if self.is_secure:
return HTTPSecurePort()
return HTTPPort()
def parse(self, content):
filenames = []
soup = BeautifulStoneSoup(content)
links = soup.table.findAll('a')
for link in links:
filenames.append(link['href'])
return '\n'.join(filenames)
class FTPConnector(Connector):
"""A concrete creator that creates a FTP connector"""
def protocol_factory_method(self):
return 'ftp'
def port_factory_method(self):
return FTPPort()
def parse(self, content):
lines = content.split('\n')
filenames = []
for line in lines:
splitted_line = line.split(None, 8)#ftp format typicallha has 8 cols
if len(splitted_line) == 9:
filenames.append(splitted_line[-1])
return '\n'.join(filenames)
#interface for our procucts
class Port(object):
__metaclass__ = abc.ABCMeta
"""Abstract product. One of its subclasses will be created in factory methods"""
@abc.abstractmethod
def __str__(self):
pass
#three subclasses implementing the Port interface
class HTTPPort(Port):
def __str__(self):
return '80'
class HTTPSecurePort(Port):
def __str__(self):
return '443'
class FTPPort(Port):
def __str__(self):
return '21'
if __name__ == '__main__':
domain = 'ftp.freebsd.org'
path = '/pub/FreeBSD/'
protocol = input('Connecting to {}. \
Which protocol to use?(0-http, 1-ftp, : '.format(domain))
if protocol == 0:
is_secure = bool(input('Use secure connection? (1-yes, 0-no): '))
connector = HTTPConnector(is_secure)
else:
is_secure = False
connector = FTPConnector(is_secure)
try:
content = connector.read(domain, path)
except urllib2.URLError, e:
print 'Can not access resourece with this method'
else:
print connector.parse(content)