Example #1
0
    def send(self, ctx, count, data):
        '''send message.'''

        p = email.Parser.Parser()
        msg = p.parsestr(data)

        # store sender and subject
        sender, subject = msg['From'], msg['Subject']
        del msg['From'], msg['Subject']
        # store remaining headers
        headers = msg.items()
        # create fresh mime message from msg body
        text = msg.get_payload()
        # for notification prefer readability over data precision
        msg = mail.mimeencode(self.ui, text, self.charsets, self.test)
        # reinstate custom headers
        for k, v in headers:
            msg[k] = v

        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")

        # try to make subject line exist and be useful
        if not subject:
            if count > 1:
                subject = _('%s: %d new changesets') % (self.root, count)
            else:
                s = ctx.description().lstrip().split('\n', 1)[0].rstrip()
                subject = '%s: %s' % (self.root, s)
        maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
        if maxsubject and len(subject) > maxsubject:
            subject = subject[:maxsubject-3] + '...'
        msg['Subject'] = mail.headencode(self.ui, subject,
                                         self.charsets, self.test)

        # try to make message have proper sender
        if not sender:
            sender = self.ui.config('email', 'from') or self.ui.username()
        if '@' not in sender or '@localhost' in sender:
            sender = self.fixmail(sender)
        msg['From'] = mail.addressencode(self.ui, sender,
                                         self.charsets, self.test)

        msg['X-Hg-Notification'] = 'changeset %s' % ctx
        if not msg['Message-Id']:
            msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' %
                                 (ctx, int(time.time()),
                                  hash(self.repo.root), socket.getfqdn()))
        msg['To'] = ', '.join(self.subs)

        msgtext = msg.as_string(0)
        if self.test:
            self.ui.write(msgtext)
            if not msgtext.endswith('\n'):
                self.ui.write('\n')
        else:
            self.ui.status(_('notify: sending %d subscribers %d changes\n') %
                           (len(self.subs), count))
            mail.sendmail(self.ui, util.email(msg['From']),
                          self.subs, msgtext)
Example #2
0
    def send(self, ctx, count, data):
        '''send message.'''

        p = email.Parser.Parser()
        msg = p.parsestr(data)

        # store sender and subject
        sender, subject = msg['From'], msg['Subject']
        del msg['From'], msg['Subject']
        # store remaining headers
        headers = msg.items()
        # create fresh mime message from msg body
        text = msg.get_payload()
        # for notification prefer readability over data precision
        msg = mail.mimeencode(self.ui, text, self.charsets, self.test)
        # reinstate custom headers
        for k, v in headers:
            msg[k] = v

        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")

        # try to make subject line exist and be useful
        if not subject:
            if count > 1:
                subject = _('%s: %d new changesets') % (self.root, count)
            else:
                s = ctx.description().lstrip().split('\n', 1)[0].rstrip()
                subject = '%s: %s' % (self.root, s)
        maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
        if maxsubject and len(subject) > maxsubject:
            subject = subject[:maxsubject - 3] + '...'
        msg['Subject'] = mail.headencode(self.ui, subject, self.charsets,
                                         self.test)

        # try to make message have proper sender
        if not sender:
            sender = self.ui.config('email', 'from') or self.ui.username()
        if '@' not in sender or '@localhost' in sender:
            sender = self.fixmail(sender)
        msg['From'] = mail.addressencode(self.ui, sender, self.charsets,
                                         self.test)

        msg['X-Hg-Notification'] = 'changeset %s' % ctx
        if not msg['Message-Id']:
            msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' % (ctx, int(
                time.time()), hash(self.repo.root), socket.getfqdn()))
        msg['To'] = ', '.join(self.subs)

        msgtext = msg.as_string(0)
        if self.test:
            self.ui.write(msgtext)
            if not msgtext.endswith('\n'):
                self.ui.write('\n')
        else:
            self.ui.status(
                _('notify: sending %d subscribers %d changes\n') %
                (len(self.subs), count))
            mail.sendmail(self.ui, util.email(msg['From']), self.subs, msgtext)
Example #3
0
    def send(self, node, count, data):
        '''send message.'''

        p = email.Parser.Parser()
        msg = p.parsestr(data)

        def fix_subject():
            '''try to make subject line exist and be useful.'''

            subject = msg['Subject']
            if not subject:
                if count > 1:
                    subject = _('%s: %d new changesets') % (self.root, count)
                else:
                    changes = self.repo.changelog.read(node)
                    s = changes[4].lstrip().split('\n', 1)[0].rstrip()
                    subject = '%s: %s' % (self.root, s)
            maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
            if maxsubject and len(subject) > maxsubject:
                subject = subject[:maxsubject-3] + '...'
            del msg['Subject']
            msg['Subject'] = subject

        def fix_sender():
            '''try to make message have proper sender.'''

            sender = msg['From']
            if not sender:
                sender = self.ui.config('email', 'from') or self.ui.username()
            if '@' not in sender or '@localhost' in sender:
                sender = self.fixmail(sender)
            del msg['From']
            msg['From'] = sender

        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
        fix_subject()
        fix_sender()

        msg['X-Hg-Notification'] = 'changeset ' + short(node)
        if not msg['Message-Id']:
            msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' %
                                 (short(node), int(time.time()),
                                  hash(self.repo.root), socket.getfqdn()))
        msg['To'] = ', '.join(self.subs)

        msgtext = msg.as_string(0)
        if self.ui.configbool('notify', 'test', True):
            self.ui.write(msgtext)
            if not msgtext.endswith('\n'):
                self.ui.write('\n')
        else:
            self.ui.status(_('notify: sending %d subscribers %d changes\n') %
                           (len(self.subs), count))
            mail.sendmail(self.ui, util.email(msg['From']),
                          self.subs, msgtext)
Example #4
0
    def send(self, node, count, data):
        '''send message.'''

        p = email.Parser.Parser()
        msg = p.parsestr(data)

        def fix_subject():
            '''try to make subject line exist and be useful.'''

            subject = msg['Subject']
            if not subject:
                if count > 1:
                    subject = _('%s: %d new changesets') % (self.root, count)
                else:
                    changes = self.repo.changelog.read(node)
                    s = changes[4].lstrip().split('\n', 1)[0].rstrip()
                    subject = '%s: %s' % (self.root, s)
            maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
            if maxsubject and len(subject) > maxsubject:
                subject = subject[:maxsubject - 3] + '...'
            del msg['Subject']
            msg['Subject'] = subject

        def fix_sender():
            '''try to make message have proper sender.'''

            sender = msg['From']
            if not sender:
                sender = self.ui.config('email', 'from') or self.ui.username()
            if '@' not in sender or '@localhost' in sender:
                sender = self.fixmail(sender)
            del msg['From']
            msg['From'] = sender

        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
        fix_subject()
        fix_sender()

        msg['X-Hg-Notification'] = 'changeset ' + short(node)
        if not msg['Message-Id']:
            msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' %
                                 (short(node), int(time.time()),
                                  hash(self.repo.root), socket.getfqdn()))
        msg['To'] = ', '.join(self.subs)

        msgtext = msg.as_string(0)
        if self.ui.configbool('notify', 'test', True):
            self.ui.write(msgtext)
            if not msgtext.endswith('\n'):
                self.ui.write('\n')
        else:
            self.ui.status(
                _('notify: sending %d subscribers %d changes\n') %
                (len(self.subs), count))
            mail.sendmail(self.ui, util.email(msg['From']), self.subs, msgtext)
Example #5
0
    def sendemail(self, address, data):
        p = email.Parser.Parser()
        msg = p.parsestr(data)
        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
        msg['To'] = address
        msg['From'] = self.emailfrom
        msg['Subject'] = 'DeliverXML'
        msg['Content-type'] = 'text/xml'
        msgtext = msg.as_string()

        self.ui.status(_('hgcia: sending update to %s\n') % address)
        mail.sendmail(self.ui, util.email(self.emailfrom), [address], msgtext)
Example #6
0
    def sendemail(self, address, data):
        p = email.Parser.Parser()
        msg = p.parsestr(data)
        msg["Date"] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
        msg["To"] = address
        msg["From"] = self.emailfrom
        msg["Subject"] = "DeliverXML"
        msg["Content-type"] = "text/xml"
        msgtext = msg.as_string()

        self.ui.status(_("hgcia: sending update to %s\n") % address)
        mail.sendmail(self.ui, util.email(self.emailfrom), [address], msgtext)
Example #7
0
    def sendemail(self, address, data):
        p = email.Parser.Parser()
        msg = p.parsestr(data)
        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")
        msg['To'] = address
        msg['From'] = self.emailfrom
        msg['Subject'] = 'DeliverXML'
        msg['Content-type'] = 'text/xml'
        msgtext = msg.as_string()

        self.ui.status(_('hgcia: sending update to %s\n') % address)
        mail.sendmail(self.ui, util.email(self.emailfrom),
                      [address], msgtext)
Example #8
0
    def send(self, ctx, count, data):
        '''send message.'''

        # Select subscribers by revset
        subs = set()
        for sub, spec in self.subs:
            if spec is None:
                subs.add(sub)
                continue
            revs = self.repo.revs('%r and %d:', spec, ctx.rev())
            if len(revs):
                subs.add(sub)
                continue
        if len(subs) == 0:
            self.ui.debug('notify: no subscribers to selected repo '
                          'and revset\n')
            return

        p = emailparser.Parser()
        try:
            msg = p.parsestr(data)
        except email.Errors.MessageParseError as inst:
            raise error.Abort(inst)

        # store sender and subject
        sender, subject = msg['From'], msg['Subject']
        del msg['From'], msg['Subject']

        if not msg.is_multipart():
            # create fresh mime message from scratch
            # (multipart templates must take care of this themselves)
            headers = msg.items()
            payload = msg.get_payload()
            # for notification prefer readability over data precision
            msg = mail.mimeencode(self.ui, payload, self.charsets, self.test)
            # reinstate custom headers
            for k, v in headers:
                msg[k] = v

        msg['Date'] = dateutil.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")

        # try to make subject line exist and be useful
        if not subject:
            if count > 1:
                subject = _('%s: %d new changesets') % (self.root, count)
            else:
                s = ctx.description().lstrip().split('\n', 1)[0].rstrip()
                subject = '%s: %s' % (self.root, s)
        maxsubject = int(self.ui.config('notify', 'maxsubject'))
        if maxsubject:
            subject = stringutil.ellipsis(subject, maxsubject)
        msg['Subject'] = mail.headencode(self.ui, subject, self.charsets,
                                         self.test)

        # try to make message have proper sender
        if not sender:
            sender = self.ui.config('email', 'from') or self.ui.username()
        if '@' not in sender or '@localhost' in sender:
            sender = self.fixmail(sender)
        msg['From'] = mail.addressencode(self.ui, sender, self.charsets,
                                         self.test)

        msg['X-Hg-Notification'] = 'changeset %s' % ctx
        if not msg['Message-Id']:
            msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' % (ctx, int(
                time.time()), hash(self.repo.root), socket.getfqdn()))
        msg['To'] = ', '.join(sorted(subs))

        msgtext = msg.as_string()
        if self.test:
            self.ui.write(msgtext)
            if not msgtext.endswith('\n'):
                self.ui.write('\n')
        else:
            self.ui.status(
                _('notify: sending %d subscribers %d changes\n') %
                (len(subs), count))
            mail.sendmail(self.ui,
                          stringutil.email(msg['From']),
                          subs,
                          msgtext,
                          mbox=self.mbox)
Example #9
0
class notifier(object):
    '''email notification class.'''
    def __init__(self, ui, repo, hooktype):
        self.ui = ui
        cfg = self.ui.config('notify', 'config')
        if cfg:
            self.ui.readconfig(cfg, sections=['usersubs', 'reposubs'])
        self.repo = repo
        self.stripcount = int(self.ui.config('notify', 'strip', 0))
        self.root = self.strip(self.repo.root)
        self.domain = self.ui.config('notify', 'domain')
        self.mbox = self.ui.config('notify', 'mbox')
        self.test = self.ui.configbool('notify', 'test', True)
        self.charsets = mail._charsets(self.ui)
        self.subs = self.subscribers()
        self.merge = self.ui.configbool('notify', 'merge', True)

        mapfile = self.ui.config('notify', 'style')
        template = (self.ui.config('notify', hooktype)
                    or self.ui.config('notify', 'template'))
        if not mapfile and not template:
            template = deftemplates.get(hooktype) or single_template
        if template:
            template = templater.parsestring(template, quoted=False)
        self.t = cmdutil.changeset_templater(self.ui, self.repo, False, None,
                                             template, mapfile, False)

    def strip(self, path):
        '''strip leading slashes from local path, turn into web-safe path.'''

        path = util.pconvert(path)
        count = self.stripcount
        while count > 0:
            c = path.find('/')
            if c == -1:
                break
            path = path[c + 1:]
            count -= 1
        return path

    def fixmail(self, addr):
        '''try to clean up email addresses.'''

        addr = util.email(addr.strip())
        if self.domain:
            a = addr.find('@localhost')
            if a != -1:
                addr = addr[:a]
            if '@' not in addr:
                return addr + '@' + self.domain
        return addr

    def subscribers(self):
        '''return list of email addresses of subscribers to this repo.'''
        subs = set()
        for user, pats in self.ui.configitems('usersubs'):
            for pat in pats.split(','):
                if '#' in pat:
                    pat, revs = pat.split('#', 1)
                else:
                    revs = None
                if fnmatch.fnmatch(self.repo.root, pat.strip()):
                    subs.add((self.fixmail(user), revs))
        for pat, users in self.ui.configitems('reposubs'):
            if '#' in pat:
                pat, revs = pat.split('#', 1)
            else:
                revs = None
            if fnmatch.fnmatch(self.repo.root, pat):
                for user in users.split(','):
                    subs.add((self.fixmail(user), revs))
        return [(mail.addressencode(self.ui, s, self.charsets, self.test), r)
                for s, r in sorted(subs)]

    def node(self, ctx, **props):
        '''format one changeset, unless it is a suppressed merge.'''
        if not self.merge and len(ctx.parents()) > 1:
            return False
        self.t.show(ctx,
                    changes=ctx.changeset(),
                    baseurl=self.ui.config('web', 'baseurl'),
                    root=self.repo.root,
                    webroot=self.root,
                    **props)
        return True

    def skipsource(self, source):
        '''true if incoming changes from this source should be skipped.'''
        ok_sources = self.ui.config('notify', 'sources', 'serve').split()
        return source not in ok_sources

    def send(self, ctx, count, data):
        '''send message.'''

        # Select subscribers by revset
        subs = set()
        for sub, spec in self.subs:
            if spec is None:
                subs.add(sub)
                continue
            revs = self.repo.revs('%r and %d:', spec, ctx.rev())
            if len(revs):
                subs.add(sub)
                continue
        if len(subs) == 0:
            self.ui.debug('notify: no subscribers to selected repo '
                          'and revset\n')
            return

        p = email.Parser.Parser()
        try:
            msg = p.parsestr(data)
        except email.Errors.MessageParseError, inst:
            raise util.Abort(inst)

        # store sender and subject
        sender, subject = msg['From'], msg['Subject']
        del msg['From'], msg['Subject']

        if not msg.is_multipart():
            # create fresh mime message from scratch
            # (multipart templates must take care of this themselves)
            headers = msg.items()
            payload = msg.get_payload()
            # for notification prefer readability over data precision
            msg = mail.mimeencode(self.ui, payload, self.charsets, self.test)
            # reinstate custom headers
            for k, v in headers:
                msg[k] = v

        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")

        # try to make subject line exist and be useful
        if not subject:
            if count > 1:
                subject = _('%s: %d new changesets') % (self.root, count)
            else:
                s = ctx.description().lstrip().split('\n', 1)[0].rstrip()
                subject = '%s: %s' % (self.root, s)
        maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
        if maxsubject:
            subject = util.ellipsis(subject, maxsubject)
        msg['Subject'] = mail.headencode(self.ui, subject, self.charsets,
                                         self.test)

        # try to make message have proper sender
        if not sender:
            sender = self.ui.config('email', 'from') or self.ui.username()
        if '@' not in sender or '@localhost' in sender:
            sender = self.fixmail(sender)
        msg['From'] = mail.addressencode(self.ui, sender, self.charsets,
                                         self.test)

        msg['X-Hg-Notification'] = 'changeset %s' % ctx
        if not msg['Message-Id']:
            msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' % (ctx, int(
                time.time()), hash(self.repo.root), socket.getfqdn()))
        msg['To'] = ', '.join(sorted(subs))

        msgtext = msg.as_string()
        if self.test:
            self.ui.write(msgtext)
            if not msgtext.endswith('\n'):
                self.ui.write('\n')
        else:
            self.ui.status(
                _('notify: sending %d subscribers %d changes\n') %
                (len(subs), count))
            mail.sendmail(self.ui,
                          util.email(msg['From']),
                          subs,
                          msgtext,
                          mbox=self.mbox)
Example #10
0
    def send(self, ctx, count, data):
        '''send message.'''

        # Select subscribers by revset
        subs = set()
        for sub, spec in self.subs:
            if spec is None:
                subs.add(sub)
                continue
            revs = self.repo.revs('%r and %d:', spec, ctx.rev())
            if len(revs):
                subs.add(sub)
                continue
        if len(subs) == 0:
            self.ui.debug('notify: no subscribers to selected repo '
                          'and revset\n')
            return

        p = email.Parser.Parser()
        try:
            msg = p.parsestr(data)
        except email.Errors.MessageParseError as inst:
            raise util.Abort(inst)

        # store sender and subject
        sender, subject = msg['From'], msg['Subject']
        del msg['From'], msg['Subject']

        if not msg.is_multipart():
            # create fresh mime message from scratch
            # (multipart templates must take care of this themselves)
            headers = msg.items()
            payload = msg.get_payload()
            # for notification prefer readability over data precision
            msg = mail.mimeencode(self.ui, payload, self.charsets, self.test)
            # reinstate custom headers
            for k, v in headers:
                msg[k] = v

        msg['Date'] = util.datestr(format="%a, %d %b %Y %H:%M:%S %1%2")

        # try to make subject line exist and be useful
        if not subject:
            if count > 1:
                subject = _('%s: %d new changesets') % (self.root, count)
            else:
                s = ctx.description().lstrip().split('\n', 1)[0].rstrip()
                subject = '%s: %s' % (self.root, s)
        maxsubject = int(self.ui.config('notify', 'maxsubject', 67))
        if maxsubject:
            subject = util.ellipsis(subject, maxsubject)
        msg['Subject'] = mail.headencode(self.ui, subject,
                                         self.charsets, self.test)

        # try to make message have proper sender
        if not sender:
            sender = self.ui.config('email', 'from') or self.ui.username()
        if '@' not in sender or '@localhost' in sender:
            sender = self.fixmail(sender)
        msg['From'] = mail.addressencode(self.ui, sender,
                                         self.charsets, self.test)

        msg['X-Hg-Notification'] = 'changeset %s' % ctx
        if not msg['Message-Id']:
            msg['Message-Id'] = ('<hg.%s.%s.%s@%s>' %
                                 (ctx, int(time.time()),
                                  hash(self.repo.root), socket.getfqdn()))
        msg['To'] = ', '.join(sorted(subs))

        msgtext = msg.as_string()
        if self.test:
            self.ui.write(msgtext)
            if not msgtext.endswith('\n'):
                self.ui.write('\n')
        else:
            self.ui.status(_('notify: sending %d subscribers %d changes\n') %
                           (len(subs), count))
            mail.sendmail(self.ui, util.email(msg['From']),
                          subs, msgtext, mbox=self.mbox)
Example #11
0
def _report_commit(ui, repo, ctx):
    domain = ui.config(b'notify_published', b'domain') or ui.config(
        b'notify', b'domain')
    messageidseed = ui.config(b'notify_published',
                              b'messageidseed') or ui.config(
                                  b'notify', b'messageidseed')
    template = ui.config(b'notify_published', b'template')
    spec = formatter.literal_templatespec(template)
    templater = logcmdutil.changesettemplater(ui, repo, spec)
    ui.pushbuffer()
    n = notify.notifier(ui, repo, b'incoming')

    subs = set()
    for sub, spec in n.subs:
        if spec is None:
            subs.add(sub)
            continue
        revs = repo.revs(b'%r and %d:', spec, ctx.rev())
        if len(revs):
            subs.add(sub)
            continue
    if len(subs) == 0:
        ui.debug(
            b'notify_published: no subscribers to selected repo and revset\n')
        return

    templater.show(
        ctx,
        changes=ctx.changeset(),
        baseurl=ui.config(b'web', b'baseurl'),
        root=repo.root,
        webroot=n.root,
    )
    data = ui.popbuffer()

    try:
        msg = mail.parsebytes(data)
    except emailerrors.MessageParseError as inst:
        raise error.Abort(inst)

    msg['In-reply-to'] = notify.messageid(ctx, domain, messageidseed)
    msg['Message-Id'] = notify.messageid(ctx, domain,
                                         messageidseed + b'-published')
    msg['Date'] = encoding.strfromlocal(
        dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2"))
    if not msg['From']:
        sender = ui.config(b'email', b'from') or ui.username()
        if b'@' not in sender or b'@localhost' in sender:
            sender = n.fixmail(sender)
        msg['From'] = mail.addressencode(ui, sender, n.charsets, n.test)
    msg['To'] = ', '.join(sorted(subs))

    msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string()
    if ui.configbool(b'notify', b'test'):
        ui.write(msgtext)
        if not msgtext.endswith(b'\n'):
            ui.write(b'\n')
    else:
        ui.status(_(b'notify_published: sending mail for %d\n') % ctx.rev())
        mail.sendmail(ui,
                      emailutils.parseaddr(msg['From'])[1],
                      subs,
                      msgtext,
                      mbox=n.mbox)
Example #12
0
    def send(self, ctx, count, data):
        '''send message.'''

        # Select subscribers by revset
        subs = set()
        for sub, spec in self.subs:
            if spec is None:
                subs.add(sub)
                continue
            revs = self.repo.revs(b'%r and %d:', spec, ctx.rev())
            if len(revs):
                subs.add(sub)
                continue
        if len(subs) == 0:
            self.ui.debug(
                b'notify: no subscribers to selected repo and revset\n')
            return

        try:
            msg = mail.parsebytes(data)
        except emailerrors.MessageParseError as inst:
            raise error.Abort(inst)

        # store sender and subject
        sender = msg[r'From']
        subject = msg[r'Subject']
        if sender is not None:
            sender = mail.headdecode(sender)
        if subject is not None:
            subject = mail.headdecode(subject)
        del msg[r'From'], msg[r'Subject']

        if not msg.is_multipart():
            # create fresh mime message from scratch
            # (multipart templates must take care of this themselves)
            headers = msg.items()
            payload = msg.get_payload(decode=pycompat.ispy3)
            # for notification prefer readability over data precision
            msg = mail.mimeencode(self.ui, payload, self.charsets, self.test)
            # reinstate custom headers
            for k, v in headers:
                msg[k] = v

        msg[r'Date'] = encoding.strfromlocal(
            dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2"))

        # try to make subject line exist and be useful
        if not subject:
            if count > 1:
                subject = _(b'%s: %d new changesets') % (self.root, count)
            else:
                s = ctx.description().lstrip().split(b'\n', 1)[0].rstrip()
                subject = b'%s: %s' % (self.root, s)
        maxsubject = int(self.ui.config(b'notify', b'maxsubject'))
        if maxsubject:
            subject = stringutil.ellipsis(subject, maxsubject)
        msg[r'Subject'] = encoding.strfromlocal(
            mail.headencode(self.ui, subject, self.charsets, self.test))

        # try to make message have proper sender
        if not sender:
            sender = self.ui.config(b'email', b'from') or self.ui.username()
        if b'@' not in sender or b'@localhost' in sender:
            sender = self.fixmail(sender)
        msg[r'From'] = encoding.strfromlocal(
            mail.addressencode(self.ui, sender, self.charsets, self.test))

        msg[r'X-Hg-Notification'] = r'changeset %s' % ctx
        if not msg[r'Message-Id']:
            msg[r'Message-Id'] = messageid(ctx, self.domain,
                                           self.messageidseed)
        msg[r'To'] = encoding.strfromlocal(b', '.join(sorted(subs)))

        msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string()
        if self.test:
            self.ui.write(msgtext)
            if not msgtext.endswith(b'\n'):
                self.ui.write(b'\n')
        else:
            self.ui.status(
                _(b'notify: sending %d subscribers %d changes\n') %
                (len(subs), count))
            mail.sendmail(
                self.ui,
                emailutils.parseaddr(msg[r'From'])[1],
                subs,
                msgtext,
                mbox=self.mbox,
            )
Example #13
0
def unlock(ui, repo, *pats, **opts):
  """
  Release Lock:
          $ hg unlock [-f] [-v] <file ...>
                If no file specified, unlock would try to relaes all availble
                locks.
          -f    Force unlock. Allows you to break others locks. Owner will
                be notified about this.
          -v    Will display a bit more information then usual.

          Other options are available only for hook execution handling.
  """
  lockFile = repo.root + pathSep + ".hg" + pathSep + "locked.files"
  user = ui.username()
  ui.note("repository: %s\n" % repo.root)
  ui.note("lockfile: %s\n" % lockFile)
  ui.note("user name: %s\n\n" % user)
  filesList=list()

  # Identify whether function is called as a hook,
  # and if so, change the command and reexecutei it.
  if 'hooktype' in opts:
    cmdline = list()
    cmdline = opts['args'].split()
    cmdline[0] = 'unlock'
    # Fixing problems around changed dispatcher (since v1.9)
    if hasattr(dispatch, 'request'):
      return(dispatch.dispatch(dispatch.request(cmdline)))
    else:
      return(dispatch.dispatch(cmdline))

  #Calculate file path in repository
  if pats:
    for file in pats:
      if not os.path.exists(file): # file defined as path in repo (via hook call)
        if file in repo.dirstate:
          filesList.append(file)
      else:
        filesList.append(PathInRepo(repo.root, file))

  # Load stored locking data
  lockedFilesList = LoadData(lockFile)

  # If files are not specified
  # try to release all available locks
  if not pats:
    filesList = lockedFilesList.keys()


  err = 0 
  for file in filesList:
    ui.note("checking: %s\n" % file) 
    if file in lockedFilesList:
      # UnLock
      if not lockedFilesList[file][UserName] == user:
      # Force unlock and send email to lock owner
        if opts['force']:
          # Email format: RFC 2822
          # example: "Vladimir Legeza <*****@*****.**>"
          from mercurial import mail
          sendFrom = util.email(user)
          sendTo = [util.email(lockedFilesList[file][UserName])]
          message = "The lock you have set on '%s' file was removed by %s." % \
           (file, lockedFilesList[file][UserName])
          ui.note("sending email to: %s\n" % sendTo)
          mail.sendmail(ui, sendFrom, sendTo, message)
          ui.note("unlocking: %s\n" % file)
          lockedFilesList.pop(file)
        else:
          err += 1
          ui.warn("%s - locked by %s.\n" % (file, lockedFilesList[file][UserName]))
      else:
        ui.note("unlocking: %s\n" % file)
        lockedFilesList.pop(file)
  if err:
    raise util.Abort(i18n._("Lock ownership violation."))

  # Save changes 
  StoreData(lockFile, lockedFilesList)
Example #14
0
    def send(self, ctx, count, data):
        '''send message.'''

        # Select subscribers by revset
        subs = set()
        for sub, spec in self.subs:
            if spec is None:
                subs.add(sub)
                continue
            revs = self.repo.revs(b'%r and %d:', spec, ctx.rev())
            if len(revs):
                subs.add(sub)
                continue
        if len(subs) == 0:
            self.ui.debug(
                b'notify: no subscribers to selected repo and revset\n')
            return

        try:
            msg = mail.parsebytes(data)
        except emailerrors.MessageParseError as inst:
            raise error.Abort(inst)

        # store sender and subject
        sender = msg['From']
        subject = msg['Subject']
        if sender is not None:
            sender = mail.headdecode(sender)
        if subject is not None:
            subject = mail.headdecode(subject)
        del msg['From'], msg['Subject']

        if not msg.is_multipart():
            # create fresh mime message from scratch
            # (multipart templates must take care of this themselves)
            headers = msg.items()
            payload = msg.get_payload(decode=pycompat.ispy3)
            # for notification prefer readability over data precision
            msg = mail.mimeencode(self.ui, payload, self.charsets, self.test)
            # reinstate custom headers
            for k, v in headers:
                msg[k] = v

        msg['Date'] = encoding.strfromlocal(
            dateutil.datestr(format=b"%a, %d %b %Y %H:%M:%S %1%2"))

        # try to make subject line exist and be useful
        if not subject:
            if count > 1:
                subject = _(b'%s: %d new changesets') % (self.root, count)
            else:
                s = ctx.description().lstrip().split(b'\n', 1)[0].rstrip()
                subject = b'%s: %s' % (self.root, s)
        maxsubject = int(self.ui.config(b'notify', b'maxsubject'))
        if maxsubject:
            subject = stringutil.ellipsis(subject, maxsubject)
        msg['Subject'] = mail.headencode(self.ui, subject, self.charsets,
                                         self.test)

        # try to make message have proper sender
        if not sender:
            sender = self.ui.config(b'email', b'from') or self.ui.username()
        if b'@' not in sender or b'@localhost' in sender:
            sender = self.fixmail(sender)
        msg['From'] = mail.addressencode(self.ui, sender, self.charsets,
                                         self.test)

        msg['X-Hg-Notification'] = 'changeset %s' % ctx
        if not msg['Message-Id']:
            msg['Message-Id'] = messageid(ctx, self.domain, self.messageidseed)
        if self.reply:
            unfi = self.repo.unfiltered()
            has_node = unfi.changelog.index.has_node
            predecessors = [
                unfi[ctx2] for ctx2 in obsutil.allpredecessors(
                    unfi.obsstore, [ctx.node()])
                if ctx2 != ctx.node() and has_node(ctx2)
            ]
            if predecessors:
                # There is at least one predecessor, so which to pick?
                # Ideally, there is a unique root because changesets have
                # been evolved/rebased one step at a time. In this case,
                # just picking the oldest known changeset provides a stable
                # base. It doesn't help when changesets are folded. Any
                # better solution would require storing more information
                # in the repository.
                pred = min(predecessors, key=lambda ctx: ctx.rev())
                msg['In-Reply-To'] = messageid(pred, self.domain,
                                               self.messageidseed)
        msg['To'] = ', '.join(sorted(subs))

        msgtext = msg.as_bytes() if pycompat.ispy3 else msg.as_string()
        if self.test:
            self.ui.write(msgtext)
            if not msgtext.endswith(b'\n'):
                self.ui.write(b'\n')
        else:
            self.ui.status(
                _(b'notify: sending %d subscribers %d changes\n') %
                (len(subs), count))
            mail.sendmail(
                self.ui,
                emailutils.parseaddr(msg['From'])[1],
                subs,
                msgtext,
                mbox=self.mbox,
            )