|
20 | 20 | from bs4 import BeautifulSoup
|
21 | 21 |
|
22 | 22 | class MySecondLifeError(Exception):
|
23 |
| - pass |
| 23 | + pass |
| 24 | + |
24 | 25 |
|
25 | 26 | class SigninError(MySecondLifeError):
|
26 |
| - pass |
| 27 | + pass |
| 28 | + |
27 | 29 |
|
28 | 30 | class MySecondLife(object):
|
29 |
| - username = None |
30 |
| - password = None |
31 |
| - |
32 |
| - def __init__(self, username, password): |
33 |
| - self.username = username |
34 |
| - self.password = password |
35 |
| - self.br = mechanize.Browser() |
36 |
| - self.br.set_handle_robots(False) # Required because SL blocks robots |
37 |
| - self._request_page('http://secondlife.com/my/account/') # Ensures we're logged in |
38 |
| - |
39 |
| - def _request_page(self, url): |
40 |
| - """Requests an account-protected page""" |
41 |
| - br = self.br |
42 |
| - br.open(url) |
43 |
| - if br.title() == "OpenId transaction in progress": |
44 |
| - br.select_form(nr=0) |
45 |
| - br.submit() |
46 |
| - if br.title() == "Second Life: Sign In": |
47 |
| - br.select_form(nr=0) |
48 |
| - br['username'] = self.username |
49 |
| - br['password'] = self.password |
50 |
| - br.submit() |
51 |
| - assert br.title() == "OpenId transaction in progress" or br.title() == "Second Life: Sign In" |
52 |
| - if br.title() == "Second Life: Sign In": |
53 |
| - try: |
54 |
| - soup = BeautifulSoup(br.response().read()) |
55 |
| - errormsg = [s for s in soup.find_all("div", class_="error")[0].strings] |
56 |
| - error = " ".join(["Sign in failed with the following error:"] + errormsg) |
57 |
| - except Exception as e: |
58 |
| - logging.exception(e) |
59 |
| - error = "Expected an OpenId transaction, but ended back up at the sign in form and couldn't locate an error message" |
60 |
| - raise SigninError(error) |
61 |
| - br.select_form(nr=0) |
62 |
| - br.submit() |
63 |
| - return br.response().read() |
64 |
| - |
65 |
| - def _extract_friends_from_html(self, html): |
66 |
| - friends = [] |
67 |
| - soup = BeautifulSoup(html) |
68 |
| - friendsoup = soup.find_all("div", class_="main-content-body") |
69 |
| - assert len(friendsoup) == 1 |
70 |
| - friendsoup = friendsoup[0].find_all("li") |
71 |
| - for spoonful in friendsoup: |
72 |
| - strings = [s for s in spoonful.strings] |
73 |
| - logging.debug("Found friend {}".format(strings)) |
74 |
| - friends.append(" ".join(strings)) |
75 |
| - return friends |
76 |
| - |
77 |
| - def friends_online(self): |
78 |
| - html = self._request_page("https://secondlife.com/my/account/friends.php?") |
79 |
| - assert self.br.title() == "Friends Online | Second Life" |
80 |
| - return self._extract_friends_from_html(html) |
| 31 | + username = None |
| 32 | + password = None |
| 33 | + |
| 34 | + def __init__(self, username, password): |
| 35 | + self.username = username |
| 36 | + self.password = password |
| 37 | + self.br = mechanize.Browser() |
| 38 | + self.br.set_handle_robots(False) # Required because SL blocks robots |
| 39 | + self._request_page('http://secondlife.com/my/account/') # Ensures we're logged in |
| 40 | + |
| 41 | + def _request_page(self, url): |
| 42 | + """Requests an account-protected page""" |
| 43 | + br = self.br |
| 44 | + br.open(url) |
| 45 | + if br.title() == "OpenId transaction in progress": |
| 46 | + br.select_form(nr=0) |
| 47 | + br.submit() |
| 48 | + if br.title() == "Second Life: Sign In": |
| 49 | + br.select_form(nr=0) |
| 50 | + br['username'] = self.username |
| 51 | + br['password'] = self.password |
| 52 | + br.submit() |
| 53 | + assert br.title() == "OpenId transaction in progress" or br.title() == "Second Life: Sign In" |
| 54 | + if br.title() == "Second Life: Sign In": |
| 55 | + try: |
| 56 | + soup = BeautifulSoup(br.response().read()) |
| 57 | + errormsg = [s for s in soup.find_all("div", class_="error")[0].strings] |
| 58 | + error = " ".join(["Sign in failed with the following error:"] + errormsg) |
| 59 | + except Exception as e: |
| 60 | + logging.exception(e) |
| 61 | + error = ("Expected an OpenId transaction, but ended back up at the " |
| 62 | + "sign in form and couldn't locate an error message") |
| 63 | + raise SigninError(error) |
| 64 | + br.select_form(nr=0) |
| 65 | + br.submit() |
| 66 | + return br.response().read() |
| 67 | + |
| 68 | + def _extract_friends_from_html(self, html): |
| 69 | + friends = [] |
| 70 | + soup = BeautifulSoup(html) |
| 71 | + friendsoup = soup.find_all("div", class_="main-content-body") |
| 72 | + assert len(friendsoup) == 1 |
| 73 | + friendsoup = friendsoup[0].find_all("li") |
| 74 | + for spoonful in friendsoup: |
| 75 | + strings = [s for s in spoonful.strings] |
| 76 | + logging.debug("Found friend {}".format(strings)) |
| 77 | + friends.append(" ".join(strings)) |
| 78 | + return friends |
| 79 | + |
| 80 | + def friends_online(self): |
| 81 | + html = self._request_page("https://secondlife.com/my/account/friends.php?") |
| 82 | + assert self.br.title() == "Friends Online | Second Life" |
| 83 | + return self._extract_friends_from_html(html) |
| 84 | + |
81 | 85 |
|
82 | 86 | class SecondLife(BotPlugin):
|
83 |
| - """Integrating your Second Life into Err""" |
84 |
| - min_err_version = '1.6.0' # Optional, but recommended |
85 |
| - max_err_version = '1.7.0' # Optional, but recommended |
86 |
| - |
87 |
| - def activate(self): |
88 |
| - if not self.config or not set(self.config).issuperset(set(("USERNAME", "PASSWORD"))): |
89 |
| - logging.info("SecondLife plugin not configured, aborting activation") |
90 |
| - else: |
91 |
| - self.mysl = MySecondLife(self.config['USERNAME'], self.config['PASSWORD']) |
92 |
| - super(SecondLife, self).activate() |
93 |
| - |
94 |
| - def get_configuration_template(self): |
95 |
| - return {'USERNAME': "some.resident", 'PASSWORD': "secret"} |
96 |
| - |
97 |
| - @botcmd(split_args_with=None) |
98 |
| - def secondlife_friends(self, mess, args): |
99 |
| - friends = self.mysl.friends_online() |
100 |
| - return str("You currently have {} friends online:\n{}".format(len(friends), "\n".join(friends).encode('utf-8', 'ignore'))) |
| 87 | + """Integrating your Second Life into Err""" |
| 88 | + min_err_version = '1.6.0' # Optional, but recommended |
| 89 | + max_err_version = '1.7.0' # Optional, but recommended |
| 90 | + |
| 91 | + def activate(self): |
| 92 | + if not self.config or not set(self.config).issuperset(set(("USERNAME", "PASSWORD"))): |
| 93 | + logging.info("SecondLife plugin not configured, aborting activation") |
| 94 | + else: |
| 95 | + self.mysl = MySecondLife(self.config['USERNAME'], self.config['PASSWORD']) |
| 96 | + super(SecondLife, self).activate() |
| 97 | + |
| 98 | + def get_configuration_template(self): |
| 99 | + return {'USERNAME': "some.resident", 'PASSWORD': "secret"} |
| 100 | + |
| 101 | + @botcmd(split_args_with=None) |
| 102 | + def secondlife_friends(self, mess, args): |
| 103 | + friends = self.mysl.friends_online() |
| 104 | + return str("You currently have {} friends online:\n{}".format(len(friends), |
| 105 | + "\n".join(friends).encode('utf-8', 'ignore'))) |
0 commit comments