Permalink
Browse files

init

  • Loading branch information...
0 parents commit a409ef348dbcd4e6befccff3a95aacab87cb67a0 @keitaoouchi committed May 18, 2012
Showing with 274 additions and 0 deletions.
  1. +29 −0 LICENSE.txt
  2. +2 −0 MANIFEST.in
  3. +84 −0 README.rst
  4. +39 −0 setup.py
  5. +120 −0 src/easyimap.py
@@ -0,0 +1,29 @@
+Copyright (c) 2004 Keita Oouchi. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. Neither the name of Keita Oouchi nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INFRAE OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,2 @@
+include LICENSE.txt README.rst
+recursive-include test *.py
@@ -0,0 +1,84 @@
+About this module
+-----------------
+imap wrapper for dog and cat.
+
+How to install
+--------------
+Requires python2.6 or later (exclude python3.x).
+You need *pip* or *distribute* or *setuptools*::
+
+ $ pip install seleniumwrapper
+
+or use easy_install::
+
+ $ easy_install seleniumwrapper
+
+also you need selenium::
+
+ $ pip install selenium
+
+Example to use
+--------------
+
+*create* function helps you to init webdriver and wrap it easily::
+
+ >>> import seleniumwrapper as selwrap
+ >>> br = selwrap.create("chrome")
+
+SeleniumWrapper delegate to its wrapped webdriver::
+
+ >>> br.get("http://www.example.com")
+ <seleniumwrapper.wrapper.SeleniumWrapper object at 0x...>
+ >>> br.xpath("//div[@class='main'])
+ <seleniumwrapper.wrapper.SeleniumWrapper object at 0x...>
+
+Setting *eager=True* to invoke find_elements::
+
+ >>> br.xpath("//a", eager=True)
+ <seleniumwrapper.wrapper.SeleniumContainerWrapper object at 0x...>
+
+SeleniumContainerWrapper also delegate to its wrapped container::
+
+ >>> links = [i.get_attribute("href") for i in br.xpath("//a", eager=True)]
+
+Each contents in SeleniumContainerWrapper also SeleniumWrapper::
+
+ >>> tds = [tr.xpath("//td", eager=True) for tr in br.xpath("//tr", eager=True)]
+
+Basic API
+---------
+* seleniumwrapper.create(drivername)
+ Create webdriver instance and wrap it with SeleniumWrapper.
+
+SeleniumWrapper
+^^^^^^^^^^^^^^^
+* unwrap
+ Retrieves WebDriver or WebElement from wrapped object.
+* parent
+ find_element_by_xpath("./parent::node()")
+* click(timeout=3, presleep=0, postsleep=0)
+ Continue to polling until timeout or element is displayed and clickable.
+* waitfor(type, target, eager=False, timeout=3)
+ See source.
+* xpath(target, eager=False, timeout=3)
+ find_element_by_xpath(target, timeout)
+* css(target, eager=False, timeout=3)
+ find_element_by_css_selector(target, timeout)
+* tag(target, eager=False, timeout=3)
+ find_element_by_tag_name(target, timeout)
+* by_text(text, tag='*', partial=False, eager=False, timeout=3)
+ similar to find_element_by_link_text or find_element_by_partial_link_text, but this method can be applicable to any tag.
+* by_class(target, eager=False, timeout=3)
+ find_element_by_class_name(target, timeout)
+* by_id(target, eager=False, timeout=3)
+ find_element_by_id(target, timeout)
+* by_name(target, eager=False, timeout=3)
+ find_element_by_name(target, timeout)
+* by_linktxt(target, eager=False, timeout=3, partial=False)
+ find_element_by_link_text(target, timeout). if partial=True, then find_element_by_partial_link_text
+* href(partialurl=None, eager=False, timeout=3):
+ find_element_by_xpath("//a", timeout). if partialurl was given, search 'a' tag which href contains partialurl.
+* img(eager=True, ext=None, timeout=3)
+ find_elements_by_xpath("//img", timeout).
+* select
+ Return Select(self.unwrap) if possible, else return None.
@@ -0,0 +1,39 @@
+from setuptools import setup
+
+from sys import version
+if version < '2.6.0':
+ raise Exception("This module doesn't support any version less than 2.6")
+
+import sys
+sys.path.append("./test")
+
+with open('README.rst', 'r') as f:
+ long_description = f.read()
+
+classifiers = [
+ 'Development Status :: 4 - Beta',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: BSD License',
+ 'Operating System :: OS Independent',
+ "Programming Language :: Python",
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.6',
+ 'Programming Language :: Python :: 2.7',
+ 'Topic :: Software Development :: Libraries :: Python Modules'
+]
+
+
+setup(
+ author='Keita Oouchi',
+ author_email='keita.oouchi@gmail.com',
+ url = 'https://github.com/keitaoouchi/seleniumwrapper',
+ name = 'seleniumwrapper',
+ version = '0.2.0',
+ package_dir={"":"src"},
+ packages = ['seleniumwrapper'],
+ test_suite = "test_seleniumwrapper.suite",
+ license='BSD License',
+ classifiers=classifiers,
+ description = 'selenium webdriver wrapper to make manipulation easier.',
+ long_description=long_description,
+)
@@ -0,0 +1,120 @@
+# -*- coding: utf-8 -*-
+
+import imaplib
+import time
+import email
+import cStringIO
+
+class MailObj(object):
+
+ def __init__(self, message):
+ self._message = message
+
+ @property
+ def title(self):
+ return self._decode_header(self._message.get('Subject'))
+
+ @property
+ def sender(self):
+ return self._decode_header(self._message.get('From'))
+
+ @property
+ def date(self):
+ return self._format_date(self._message.get('Date'))
+
+ @property
+ def datestr(self):
+ return time.strftime("%d %b %Y %H:%M", self.date)
+
+ @property
+ def body(self):
+ for part in self._message.walk():
+ if part.get_content_maintype() != 'multipart' and not part.get_filename():
+ return self._decode_body(part)
+ raise Exception("凸[-_-]")
+
+ def __str__(self):
+ date_format = ""
+ template = "{date}", "{sender}", "{title}"
+ return " || ".join(template).format(date=self.datestr, sender=self.sender, title=self.title)
+
+ def _decode_header(self, data):
+ decoded_headers = email.Header.decode_header(data)
+ headers = []
+ for decoded_str, charset in decoded_headers:
+ if charset:
+ headers.append(unicode(decoded_str, charset))
+ else:
+ headers.append(unicode(decoded_str))
+ return "".join(headers)
+
+
+ def _decode_body(self, part):
+ charset = str(part.get_content_charset())
+ body = unicode(part.get_payload(), charset) if charset else part.get_payload()
+ return body
+
+ def _format_date(self, date_string):
+ format_pattern = '%a, %d %b %Y %H:%M:%S +'
+ if date_string[0].isdigit():
+ format_pattern = '%d %b %Y %H:%M:%S'
+ return time.strptime(date_string[0:-6], format_pattern)
+
+class MailerGateway(object):
+
+ def __init__(self, mailer, *criteria):
+ self._mailer = mailer
+ self._ids = mailer.search(None, criteria)[1][0].split()
+
+ @property
+ def ids(self):
+ return self._ids
+
+ def _parse_email(self, data):
+ message = email.message_from_string(data)
+ return MailObj(message)
+
+ def listup_mails(self, limit=10):
+ emailids = self.ids
+ emailids.reverse()
+ result = []
+ for num in emailids[:limit]:
+ typ, content = self._mailer.fetch(num, '(RFC822)')
+ mail = self._parse_email(content[0][1])
+ result.append((int(num), mail))
+ return result
+
+ def get_body(self, id):
+ typ, content = self._mailer.fetch(id, '(RFC822)')
+ mail = self._parse_email(content[0][1])
+ return mail.body
+
+ def quit(self):
+ self._mailer.close()
+ self._mailer.logout()
+
+class MailerFacade(object):
+
+ def __init__(self, host, user, password, mailbox):
+ self._mailgw = MailerGateway(self._get_mailer(host, user, password, mailbox))
+
+ def _get_mailer(self, host, user, password, mailbox='INBOX'):
+ M = imaplib.IMAP4_SSL(host=host)
+ M.login(user, password)
+ M.select(mailbox)
+ return M
+
+ def quit(self):
+ """close and logout"""
+ self._mailgw.quit()
+
+ def listup(self, limit=10):
+ """return list of tuples(email_id, mail_object)"""
+ return self._mailgw.listup_mails(limit)
+
+ def body(self, id):
+ """return string of email body"""
+ return self._mailgw.get_body(id)
+
+def create(host, user, password, mailbox):
+ return MailerFacade(host, user, password, mailbox)

0 comments on commit a409ef3

Please sign in to comment.