class NotifyAuthorAboutRestore(Command): def __init__(self, project, env): Command.__init__(self) self.name = "NotifyAuthorAboutRestore" self.project = project self.notifier = NotificationSystem(env) from_email = env.config["notification"].get("smtp_from") replyto_email = env.config["notification"].get("smtp_replyto") self.from_email = from_email or replyto_email def do(self): author = self.project.author try: if author: txt = "Your project '" + self.project.project_name + "' have been restored and should " txt += "be accessible in " + self.project.get_url() + "\n\n" txt += "Permissions have not been restored automatically. You should add manually all " txt += "permissions again. Listings in the below will help if you want to give similar " txt += "permissions that project used to have.\n\n" team = self.project.archive_path + "/team.txt" f = open(team, "r") txt += f.read() f.close() self.notifier.send_email(self.from_email, author.mail, txt) except Exception, e: conf.log.debug("Writing restore notification failed.") conf.log.exception(e) return True
class NotifyAuthorAboutRestore(Command): def __init__(self, project, env): Command.__init__(self) self.name = "NotifyAuthorAboutRestore" self.project = project self.notifier = NotificationSystem(env) from_email = env.config['notification'].get('smtp_from') replyto_email = env.config['notification'].get('smtp_replyto') self.from_email = from_email or replyto_email def do(self): author = self.project.author try: if author: txt = "Your project '" + self.project.project_name + "' have been restored and should " txt += "be accessible in " + self.project.get_url() + "\n\n" txt += "Permissions have not been restored automatically. You should add manually all " txt += "permissions again. Listings in the below will help if you want to give similar " txt += "permissions that project used to have.\n\n" team = self.project.archive_path + "/team.txt" f = open(team, 'r') txt += f.read() f.close() self.notifier.send_email(self.from_email, author.mail, txt) except Exception, e: conf.log.debug("Writing restore notification failed.") conf.log.exception(e) return True
def __init__(self, project, env): Command.__init__(self) self.name = "NotifyAuthorAboutRestore" self.project = project self.notifier = NotificationSystem(env) from_email = env.config['notification'].get('smtp_from') replyto_email = env.config['notification'].get('smtp_replyto') self.from_email = from_email or replyto_email
def send_mail(message, receiver): env = Environment(conf.getEnvironmentSysPath(conf.sys_home_project_name)) notifier = NotificationSystem(env) from_email = env.config['notification'].get('smtp_from') replyto_email = env.config['notification'].get('smtp_replyto') sender = from_email or replyto_email try: notifier.send_email(sender, receiver, message) except Exception as e: error_exit(e) return True
def __init__(self, project, env): Command.__init__(self) self.name = "NotifyAuthorAboutRestore" self.project = project self.notifier = NotificationSystem(env) from_email = env.config["notification"].get("smtp_from") replyto_email = env.config["notification"].get("smtp_replyto") self.from_email = from_email or replyto_email
class RegistrationModule(Component): """Provides users the ability to register a new account. Requires configuration of the AccountManager module in trac.ini. """ implements(INavigationContributor, IRequestHandler, ITemplateProvider) def __init__(self): self._enable_check(log=True) def _enable_check(self, log=False): writable = AccountManager(self.env).supports('set_password') ignore_case = auth.LoginModule(self.env).ignore_case if log: if not writable: self.log.warn('RegistrationModule is disabled because the ' 'password store does not support writing.') if ignore_case: self.log.warn('RegistrationModule is disabled because ' 'ignore_auth_case is enabled in trac.ini. ' 'This setting needs disabled to support ' 'registration.') return writable and not ignore_case #INavigationContributor methods def get_active_navigation_item(self, req): return 'register' def get_navigation_items(self, req): if not self._enable_check(): return if req.authname == 'anonymous': yield 'metanav', 'register', Markup('<a href="%s">Register</a>', (self.env.href.register())) # IRequestHandler methods def match_request(self, req): return req.path_info == '/register' and self._enable_check(log=True) def process_request(self, req): if req.authname != 'anonymous': req.redirect(self.env.href.account()) action = req.args.get('action') if req.method == 'POST' and action == 'create': try: _create_user(req, self.env) except TracError, e: req.hdf['registration.error'] = e.message else: req.redirect(self.env.href.login()) req.hdf['reset_password_enabled'] = \ (self.env.is_component_enabled(AccountModule) and NotificationSystem(self.env).smtp_enabled) return 'register.cs', None
def _hash_msgid(env, source, from_email): hash_type = NotificationSystem(env).message_id_hash try: h = hashlib.new(hash_type) except: raise ConfigurationError( _("Unknown hash type '%(type)s'", type=hash_type)) h.update(source) host = from_email[from_email.find('@') + 1:] return '<%03d.%s@%s>' % (len(source), h.hexdigest(), host)
def reset_password_enabled(self): return (self.env.is_component_enabled(AccountModule) and NotificationSystem(self.env).smtp_enabled and self._write_check())
def send(self, torcpts, ccrcpts, mime_headers={}): from email.MIMEText import MIMEText from email.Utils import formatdate attach_diff = self.config.getbool('wiki-notification', 'attach_diff') if attach_diff: from email.MIMEMultipart import MIMEMultipart self.data["wikidiff"] = None charset = str(self._charset) stream = self.template.generate(**self.data) # don't translate the e-mail stream t = deactivate() try: body = stream.render('text', encoding=charset) finally: reactivate(t) # self.env.log.debug('Email Contents: %s', body) public_cc = self.config.getbool('wiki-notification', 'use_public_cc') headers = {} headers['X-Mailer'] = 'Trac %s, by Edgewall Software' % __version__ headers['X-Trac-Version'] = __version__ headers['X-Trac-Project'] = self.env.project_name headers['X-URL'] = self.env.project_url headers['Precedence'] = 'bulk' headers['Auto-Submitted'] = 'auto-generated' headers['Subject'] = self.subject headers['From'] = ( self.from_name, self.from_email) if self.from_name else self.from_email headers['Reply-To'] = self.replyto_email def build_addresses(rcpts): """Format and remove invalid addresses""" return filter(lambda x: x, [self.get_smtp_address(addr) for addr in rcpts]) blocked_addresses = [] def remove_dup(rcpts, all): """Remove duplicates""" tmp = [] for rcpt in rcpts: if rcpt in self.banned_addresses: self.env.log.debug("Banned Address: %s", rcpt) blocked_addresses.append(rcpt) elif not rcpt in all: tmp.append(rcpt) all.append(rcpt) return (tmp, all) toaddrs = build_addresses(torcpts) ccaddrs = build_addresses(ccrcpts) accaddrs = build_addresses( self.config.getlist('wiki-notification', 'smtp_always_cc', [])) bccaddrs = build_addresses( self.config.getlist('wiki-notification', 'smtp_always_bcc', [])) recipients = [] (toaddrs, recipients) = remove_dup(toaddrs, recipients) (ccaddrs, recipients) = remove_dup(ccaddrs, recipients) (accaddrs, recipients) = remove_dup(accaddrs, recipients) (bccaddrs, recipients) = remove_dup(bccaddrs, recipients) self.env.log.debug("Not notifying the following addresses: %s", ', '.join(blocked_addresses)) # if there is not valid recipient, leave immediately if len(recipients) < 1: self.env.log.info('no recipient for a wiki notification') return dest = self.change_author or 'anonymous' headers['X-Trac-Wiki-URL'] = self.data['link'] pcc = accaddrs if public_cc: pcc += ccaddrs if toaddrs: headers['To'] = ', '.join(toaddrs) if pcc: headers['Cc'] = ', '.join(pcc) headers['Date'] = formatdate() if attach_diff: # With MIMEMultipart the charset has to be set before any parts # are added. msg = MIMEMultipart('mixed', None, [], charset=charset) msg.preamble = 'This is a multi-part message in MIME format.' # The text Message mail = MIMEText(body, 'plain', charset) mail.add_header('Content-Disposition', 'inline', filename="message.txt") msg.attach(mail) try: # The Diff Attachment attach = MIMEText(self.wikidiff.encode('utf-8'), 'x-patch', charset) attach.add_header('Content-Disposition', 'inline', filename=self.page.name + '.diff') msg.attach(attach) except AttributeError: # We don't have a wikidiff to attach pass else: msg = MIMEText(body, 'plain', charset) self.add_headers(msg, headers) self.add_headers(msg, mime_headers) self.env.log.info("Sending notification to %s" % (recipients, )) try: NotificationSystem(self.env).send_email(self.from_email, recipients, msg.as_string()) except Exception, err: self.env.log.debug('Notification could not be sent: %r', err)
def send(self, torcpts, ccrcpts, mime_headers={}): """ this method is based NotifyEmail in trac/notification.py As the default trac NotifyEmail class assumes alot, and will overwrite headers we do not call our ancestor class method here, but send the mail direct """ from email.MIMEText import MIMEText from email.Utils import formatdate stream = self.template.generate(**self.data) # don't translate the e-mail stream t = deactivate() try: body = stream.render('text') finally: reactivate(t) projname = self.env.project_name public_cc = self.config.getbool('notification', 'use_public_cc') headers = {} headers['X-Mailer'] = 'Trac %s, by Edgewall Software' % __version__ headers['X-Trac-Version'] = __version__ headers['X-Trac-Project'] = projname headers['X-URL'] = self.env.project_url headers['Precedence'] = 'bulk' headers['Auto-Submitted'] = 'auto-generated' headers['Subject'] = self.subject headers['From'] = (self.from_name or projname, self.from_email) headers['Reply-To'] = self.reply_to_email # add Message-ID and In-Reply-To for threaded mail clients if self.action == 'post_created': headers['Message-ID'] = self.get_message_id( projname, self.blog.name) else: headers['Message-ID'] = self.get_message_id( projname, self.blog.name, self.time) headers['In-Reply-To'] = headers[ 'References'] = self.get_message_id(projname, self.blog.name) def build_addresses(rcpts): """Format and remove invalid addresses""" return filter(lambda x: x, [self.get_smtp_address(addr) for addr in rcpts]) def remove_dup(rcpts, all): """Remove duplicates""" tmp = [] for rcpt in rcpts: if not rcpt in all: tmp.append(rcpt) all.append(rcpt) return (tmp, all) toaddrs = build_addresses(torcpts) ccaddrs = build_addresses(ccrcpts) accparam = self.config.getlist('fullblog-notification', 'smtp_always_cc') accaddrs = accparam and build_addresses(accparam) or [] recipients = [] (toaddrs, recipients) = remove_dup(toaddrs, recipients) (ccaddrs, recipients) = remove_dup(ccaddrs, recipients) (accaddrs, recipients) = remove_dup(accaddrs, recipients) # if there is not valid recipient, leave immediately if len(recipients) < 1: self.env.log.info('no recipient for a fullblog notification') return cc = accaddrs + ccaddrs if cc: headers['Cc'] = ', '.join(cc) if toaddrs: headers['To'] = ', '.join(toaddrs) headers['Date'] = formatdate() msg = MIMEText(body, 'plain') # Message class computes the wrong type from MIMEText constructor, # which does not take a Charset object as initializer. Reset the # encoding type to force a new, valid evaluation del msg['Content-Transfer-Encoding'] msg.set_charset(self._charset) self.add_headers(msg, headers) self.add_headers(msg, mime_headers) NotificationSystem(self.env).send_email(self.from_email, recipients, msg.as_string())