コード例 #1
0
ファイル: viewhtmlmsg.py プロジェクト: s5unty/muttils
 def view(self):
     try:
         if self.inp:
             if len(self.inp) > 1:
                 raise util.DeadMan('only 1 argument allowed')
             fp = open(self.inp[0], 'rb')
         else:
             fp = sys.stdin
         msg = email.message_from_file(fp)
         if self.inp:
             fp.close()
     except email.Errors.MessageParseError, inst:
         raise util.DeadMan(inst)
コード例 #2
0
ファイル: tpager.py プロジェクト: s5unty/muttils
 def __init__(self, ui, items=None, name='item',
              fmt='sf', ckey='', qfunc='quit', crit='pattern'):
     self.ui = ui
     self.items = items or [] # (text) items to choose from
     self.name = name         # general name of an item
     self.fmt = fmt
     if self.fmt not in ('sf', 'bf'):
         raise util.DeadMan('%s: invalid format, use one of "sf", "bf"'
                            % self.fmt)
     self.ckey = ckey         # key to customize pager
     if self.ckey in ('q', 'Q', '-'):
         raise util.DeadMan("the `%s' key is internally reserved."
                            % self.ckey)
     self.qfunc = qfunc       # name of exit function
     self.crit = crit         # name of criterion for customizing
コード例 #3
0
ファイル: ui.py プロジェクト: s5unty/muttils
 def resolveopts(self, options):
     '''Adapts option sets.
     Sets protocol to "web", if "getdir" is without corresponding
     protocol scheme.
     Sets protocol to "mid", if it encounters one of messageopts.
     And, finally, update ui's attributes with current options.'''
     webschemes = ('web', 'http', 'ftp')
     messageopts = ('midrelax', 'news', 'local', 'browse', 'kiosk',
                    'mhiers', 'specdirs', 'mask')
     if options.get('getdir', '') and options['proto'] not in webschemes:
         options['proto'] = 'web'
     if options['proto'] != 'mid':
         for o in messageopts:
             val = options[o]
             if (val or val is not None and
                 (o == 'mhiers' or o == 'specdirs')):
                 options['proto'] = 'mid'
                 options['decl'] = not options['midrelax']
                 break
     else:
         options['decl'] = True
     del options['midrelax']
     try:
         for o in options.iterkeys():
             setattr(self, o, options[o])
     except KeyError:
         raise util.DeadMan('%s: invalid option' % o)
コード例 #4
0
ファイル: ui.py プロジェクト: s5unty/muttils
 def updateconfig(self):
     if self.updated:
         return
     try:
         self.config.read(self.rcpath)
     except ConfigParser.ParsingError, inst:
         raise util.DeadMan(inst)
コード例 #5
0
 def filedeconstructor(self, fn):
     '''Checks if given file object is message or mailbox.
     If no, returns text contents of file or empty string if file is binary.
     Parses message/mailbox for relevant headers adding urls to list of items
     and returns text parts for further searching.'''
     # binary check from mercurial.util
     fp = open(fn, 'rb')
     try:
         text = fp.read()
         if '\0' in text:
             return ''
         elif self.ui.text:
             return text
         msg = _msgfactory(fp)
         if not msg:
             return text
         # else it's a message or a mailbox
         if not msg['message-id']:
             hint = ('make sure input is a raw message'
                     ' - in mutt: unset pipe_decode -,'
                     ' or use -t/--text to disable message detection')
             raise util.DeadMan('no message-id found', hint=hint)
         if not msg.get_unixfrom():
             textlist = self.msgharvest(msg)
         else: # treat text like a mailbox because it might be one
             textlist = [] # list of strings to search
             mbox = mailbox.PortableUnixMailbox(fp, _msgfactory)
             while msg is not None:
                 msg = mbox.next()
                 if msg:
                     textlist += self.msgharvest(msg)
     finally:
         fp.close()
     return '\n'.join(textlist)
コード例 #6
0
ファイル: sigpager.py プロジェクト: s5unty/muttils
 def sign(self):
     self.sdir = util.absolutepath(self.sdir)
     sl = [f for f in os.listdir(self.sdir) if f.endswith(self.tail)]
     if not sl:
         raise util.DeadMan('no signature files in %s' % self.sdir)
     self.sigs = [sig for sig in map(self.getstring, sl) if sig]
     weed_re = None
     while True:
         reply = self.getsig(weed_re)
         if reply.startswith(self.ckey):
             weed_re = self.checkpattern(reply[1:])
         else:
             break
     if self.items is not None:
         if self.items:
             sig = self.sep + self.items[0]
         else:
             self.sig = util.absolutepath(self.sig)
             fp = open(self.sig)
             try:
                 sig = self.sep + fp.read()
             finally:
                 fp.close()
         if not self.dest:
             self.ui.write(sig)
         else:
             for fn in self.dest:
                 fp = open(fn, 'a')
                 try:
                     fp.write(sig)
                 finally:
                     fp.close()
     elif self.dest:
         self.ui.write('\n')
コード例 #7
0
ファイル: ui.py プロジェクト: s5unty/muttils
 def configint(self, section, name, default=0):
     cfg = self.configitem(section, name)
     if cfg is None:
         return default
     try:
         return int(cfg)
     except ValueError, inst:
         raise util.DeadMan(inst)
コード例 #8
0
ファイル: viewhtmlmsg.py プロジェクト: s5unty/muttils
 def ivisit(self):
     try:
         fd = inotifyx.init()
         wd = inotifyx.add_watch(fd, self.items[0], inotifyx.IN_CLOSE)
         self.urlvisit()
         inotifyx.get_events(fd, self.keep)
         inotifyx.rm_watch(fd, wd)
         os.close(fd)
     except IOError:
         hint = ('consider increasing '
                 '/proc/sys/fs/inotify/max_user_watches')
         raise util.DeadMan('failed to enable inotify', hint=hint)
コード例 #9
0
 def kiosktest(self):
     '''Provides the path to an mbox file to store retrieved messages.'''
     if not self.ui.kiosk:
         self.ui.kiosk = tempfile.mkstemp(prefix='kiosk.')[1]
         return
     self.ui.kiosk = util.absolutepath(self.ui.kiosk)
     if (not os.path.exists(self.ui.kiosk) or
         not os.path.getsize(self.ui.kiosk)):
         # non existant or empty is fine
         return
     if not os.path.isfile(self.ui.kiosk):
         raise util.DeadMan('%s: not a regular file' % self.ui.kiosk)
     fp = open(self.ui.kiosk, 'rb')
     try:
         testline = fp.readline()
     finally:
         fp.close()
     try:
         p = email.Parser.Parser()
         check = p.parsestr(testline, headersonly=True)
     except email.Errors.HeaderParseError, inst:
         raise util.DeadMan(inst)
コード例 #10
0
ファイル: wget.py プロジェクト: s5unty/muttils
 def download(self, urls):
     self.ui.getdir = util.savedir(self.ui.getdir)
     for url in map(urlregex.webschemecomplete, urls):
         bn = url.rstrip('/').split('/')[-1]
         path = os.path.join(self.ui.getdir, bn)
         self.ui.note('downloading to %s ...\n' % path)
         s = self.request(url)
         if s:
             try:
                 fp = open(path, 'wb')
                 fp.write(s)
                 fp.close()
             except IOError, inst:
                 raise util.DeadMan(inst)
コード例 #11
0
 def formwrap(self):
     '''Checks excluding regexes and passes data to iterator.'''
     for i in self.defwidth, self.tabwidth:
         if not isinstance(i, int):
             raise util.DeadMan('integer expected, got "%s"' % i)
     try:
         if self.inp is None:
             lit = sys.stdin
         else:
             lit = iter(self.inp.splitlines(True))
         self.literator(lit)
     except AttributeError: # list of files
         for f in self.inp:
             lit = open(f, 'rb')
             try:
                 self.literator(lit)
             finally:
                 lit.close()
コード例 #12
0
ファイル: wget.py プロジェクト: s5unty/muttils
 def request(self, req, func='r'):
     result = None
     try:
         fp = self.opener.open(req)
         if func == 'r':
             result = fp.read()
         elif func == 'g':
             result = fp.geturl()
         elif func == 'i':
             result = fp.info()
         else:
             raise util.DeadMan('%s: invalid request instruction')
         fp.close()
     except urllib2.URLError, inst:
         if util.safehasattr(inst, 'reason'):
             self.ui.warn('failed to reach a server for %s\n' % req,
                          'reason: %s\n' % inst)
         else:
             self.ui.warn('server failure for %s\n' % req,
                          'error code: %s\n' % inst)
コード例 #13
0
class kiosk(object):
    '''
    Provides methods to search for and retrieve
    messages via their Message-ID.
    '''
    mspool = ''         # path to local mail spool
    msgs = []           # list of retrieved message objects
    muttone = True      # configure mutt for display of 1 msg only
    mdmask = '^(cur|new|tmp)$'

    def __init__(self, ui, items=None):
        self.ui = ui
        self.items = items or []

    def kiosktest(self):
        '''Provides the path to an mbox file to store retrieved messages.'''
        if not self.ui.kiosk:
            self.ui.kiosk = tempfile.mkstemp(prefix='kiosk.')[1]
            return
        self.ui.kiosk = util.absolutepath(self.ui.kiosk)
        if (not os.path.exists(self.ui.kiosk) or
            not os.path.getsize(self.ui.kiosk)):
            # non existant or empty is fine
            return
        if not os.path.isfile(self.ui.kiosk):
            raise util.DeadMan('%s: not a regular file' % self.ui.kiosk)
        fp = open(self.ui.kiosk, 'rb')
        try:
            testline = fp.readline()
        finally:
            fp.close()
        try:
            p = email.Parser.Parser()
            check = p.parsestr(testline, headersonly=True)
        except email.Errors.HeaderParseError, inst:
            raise util.DeadMan(inst)
        if check.get_unixfrom():
            self.muttone = False
        else:
            raise util.DeadMan('%s: not a unix mailbox' % self.ui.kiosk)
コード例 #14
0
 def urlobject(self, search=True):
     '''Creates customized regex objects of url.'''
     kill_re = None
     if self.ui.proto not in valid_protos:
         raise util.DeadMan(self.ui.proto,
                            ': invalid protocol parameter, use one of:\n',
                            ', '.join(valid_protos))
     if self.ui.proto == 'mailto':  # be pragmatic and list not only declared
         self.url_re = _get_mailre()
     elif self.ui.proto != 'mid':
         self.url_re = re.compile(self.getraw(search),
                                  re.IGNORECASE | re.VERBOSE)
         if search:
             kill_re = re.compile(r'^url:\s?|\s+', re.IGNORECASE)
     elif self.ui.decl:
         self.url_re = re.compile(_declmidpat(), re.IGNORECASE | re.VERBOSE)
         if search:
             kill_re = re.compile(_nntppat(), re.IGNORECASE | re.VERBOSE)
     else:
         self.url_re = re.compile(r'(\b%s\b)' % _midpat(),
                                  re.IGNORECASE | re.VERBOSE)
     return kill_re
コード例 #15
0
 def urlcollect(self):
     '''Harvests urls from stdin or files.'''
     if not self.files: # stdin
         tempname = tempfile.mkstemp(prefix='urlcollector.')[1]
         fp = open(tempname, 'wb')
         try:
             fp.write(sys.stdin.read())
         finally:
             fp.close()
         text = self.filedeconstructor(tempname)
         os.unlink(tempname)
     else:
         textlist = []
         for fn in self.files:
             textlist.append(self.filedeconstructor(util.absolutepath(fn)))
         text = '\n'.join(textlist)
     if text:
         self.findurls(text)
     if self.ui.pat and self.items:
         try:
             ui_re = re.compile(r'%s' % self.ui.pat, re.IGNORECASE)
         except re.error, err:
             raise util.DeadMan("%s in pattern `%s'" % (err, self.ui.pat))
         self.items = [i for i in self.items if ui_re.search(i)]
コード例 #16
0
ファイル: viewhtmlmsg.py プロジェクト: s5unty/muttils
class viewhtml(pybrowser.browser):
    def __init__(self, safe, keep, app, args):
        self.ui = ui.ui()
        self.ui.updateconfig()
        pybrowser.browser.__init__(self, parentui=self.ui,
                                   app=app, evalurl=True)
        self.inp = args
        self.safe = safe or self.ui.configbool('html', 'safe')
        self.keep = keep
        if self.keep is None:
            self.keep = self.ui.configint('html', 'keep', 3)

    def cleanup(self, tmpdir):
        if self.keep:
            shutil.rmtree(tmpdir)

    def ivisit(self):
        try:
            fd = inotifyx.init()
            wd = inotifyx.add_watch(fd, self.items[0], inotifyx.IN_CLOSE)
            self.urlvisit()
            inotifyx.get_events(fd, self.keep)
            inotifyx.rm_watch(fd, wd)
            os.close(fd)
        except IOError:
            hint = ('consider increasing '
                    '/proc/sys/fs/inotify/max_user_watches')
            raise util.DeadMan('failed to enable inotify', hint=hint)

    def view(self):
        try:
            if self.inp:
                if len(self.inp) > 1:
                    raise util.DeadMan('only 1 argument allowed')
                fp = open(self.inp[0], 'rb')
            else:
                fp = sys.stdin
            msg = email.message_from_file(fp)
            if self.inp:
                fp.close()
        except email.Errors.MessageParseError, inst:
            raise util.DeadMan(inst)
        if not msg:
            raise util.DeadMan('input not a message')
        if not msg['message-id']:
            hint = ('make sure input is a raw message,'
                    ' in mutt: unset pipe_decode')
            raise util.DeadMan('no message-id found', hint=hint)
        htiter = email.Iterators.typed_subpart_iterator(msg, subtype='html')
        try:
            html = htiter.next()
        except StopIteration:
            raise util.DeadMan('no html found')
        htmldir = tempfile.mkdtemp('', 'viewhtmlmsg.')
        try:
            htmlfile = os.path.join(htmldir, 'index.html')
            charset = html.get_param('charset')
            html = html.get_payload(decode=True)
            if charset:
                charsetmeta = '<meta charset="%s">' % charset
                if '<head>' in html:
                    html = html.replace('<head>', '<head>%s' % charsetmeta)
                else:
                    html = '<head>%s</head>%s' % (charsetmeta, html)
            fc = 0
            for part in msg.walk():
                fc += 1
                fn = (part.get_filename() or part.get_param('filename') or
                      part.get_param('name', 'prefix_%d' % fc))
                if part['content-id']:
                    # safe ascii filename: replace it with cid
                    fn = email.Utils.unquote(part['content-id'])
                    html = html.replace('"cid:%s"' % fn, "%s" % fn)
                fpay = part.get_payload(decode=True)
                if fpay:
                    fp = open(os.path.join(htmldir, fn), 'wb')
                    fp.write(fpay)
                    fp.close()
            if self.safe:
                spat = r'(src|background)\s*=\s*["\']??https??://[^"\'>]*["\'>]'
                html = re.sub(spat, r'\1="#"', html)
            fp = open(htmlfile, 'wb')
            fp.write(html)
            fp.close()
            self.items = [htmlfile]
            if self.keep:
                try:
                    self.ivisit()
                except NameError:
                    self.urlvisit()
                    time.sleep(self.keep)
            else:
                self.urlvisit()
        finally:
            self.cleanup(htmldir)
コード例 #17
0
 def maskompile(self):
     try:
         self.ui.mask = re.compile(r'%s' % self.ui.mask)
     except re.error, inst:
         raise util.DeadMan("%s in pattern `%s'" % (inst, self.ui.mask))
コード例 #18
0
def _mrex(pat):
    '''Checks and returns MULTILINE regex of pat.'''
    try:
        return re.compile(r'%s' % pat, re.MULTILINE)
    except re.error, inst:
        raise util.DeadMan("error in pattern `%s': %s" % (pat, inst))