def test_everything_else_unchanged(self): for mem in ((None, None), ("", ""), ("abc", "abc")): self.eq_(tools.urlencode_text(mem[0]), mem[1])
def test_none_to_none(self): self.eq_(tools.urlencode_text(None), None)
def send_email(config, entry, comment, comment_dir, comment_filename): """Send an email to the blog owner on a new comment @param config: configuration as parsed by Pyblosxom @type config: dictionary @param entry: a file entry @type config: dictionary @param comment: comment as generated by read_comments @type comment: dictionary @param comment_dir: the comment directory @type comment_dir: string @param comment_filename: file name of current comment @type comment_filename: string """ import smtplib # import the formatdate function which is in a different # place in Python 2.3 and up. try: from email.Utils import formatdate except ImportError: from rfc822 import formatdate from socket import gethostbyaddr author = escape_smtp_commands(clean_author(comment['author'])) description = escape_smtp_commands(comment['description']) ipaddress = escape_smtp_commands(comment.get('ipaddress', '?')) if 'comment_smtp_from' in config: email = config['comment_smtp_from'] else: email = escape_smtp_commands(clean_author(comment['email'])) try: curl = "%s/%s" % (config['base_url'], tools.urlencode_text(entry['file_path'])) comment_dir = os.path.join(config['comment_dir'], entry['absolute_path']) # create the message message = [] message.append("Name: %s" % author) if 'email' in comment: message.append("Email: %s" % comment['email']) if 'link' in comment: message.append("URL: %s" % comment['link']) try: host_name = gethostbyaddr(ipaddress)[0] message.append("Hostname: %s (%s)" % (host_name, ipaddress)) # FIXME - bare except here--bad! except: message.append("IP: %s" % ipaddress) message.append("Entry URL: %s" % curl) message.append("Comment location: %s" % comment_filename) message.append("\n\n%s" % description) if 'comment_mta_cmd' in config: # set the message headers message.insert(0, "") message.insert(0, "Subject: comment on %s" % curl) message.insert(0, "Date: %s" % formatdate(float(comment['pubDate']))) message.insert(0, "To: %s" % config["comment_smtp_to"]) message.insert(0, "From: %s" % email) body = '\n'.join(message).encode('utf-8') argv = [config['comment_mta_cmd'], '-s', '"comment on %s"' % curl, config['comment_smtp_to']] # FIXME - switch to subprocess when we can require python 2.4 process = popen2.Popen3(argv, capturestderr=True) process.tochild.write(body) process.tochild.close() process.wait() stdout = process.fromchild.read() stderr = process.childerr.read() tools.get_logger().debug('Ran MTA command: ' + ' '.join(argv)) tools.get_logger().debug('Received stdout: ' + stdout) tools.get_logger().debug('Received stderr: ' + stderr) # the except clause below will catch this assert stderr == '', stderr else: assert 'comment_smtp_server' in config server = smtplib.SMTP(config['comment_smtp_server']) mimemsg = MIMEText("\n".join(message).encode("utf-8"), 'plain', 'utf-8') # set the message headers mimemsg["From"] = email mimemsg["To"] = config["comment_smtp_to"] mimemsg["Date"] = formatdate(float(comment["pubDate"])) mimemsg["Subject"] = ("comment on %s" % curl) # send the message via smtp server.sendmail(from_addr=email, to_addrs=config['comment_smtp_to'], msg=mimemsg.as_string()) server.quit() except Exception, e: tools.get_logger().error("error sending email: %s" % traceback.format_exception(*sys.exc_info()))
def test_none_to_none(self): assert tools.urlencode_text(None) == None
def test_utf8(self): self.eq_(tools.urlencode_text("español"), "espa%C3%B1ol")
def _subCategories(self, elist, root, rootname): config = self._request.getConfiguration() form = self._request.getForm() flavour = (form.has_key('flav') and form['flav'].value or config.get('default_flavour', 'html')) start_t = config.get("category_start", DEFAULT_START) begin_t = config.get("category_begin", DEFAULT_BEGIN) item_t = config.get("category_item", DEFAULT_ITEM) end_t = config.get("category_end", DEFAULT_END) finish_t = config.get("category_finish", DEFAULT_FINISH) # peel off the root dir from the list of entries elist = [mem[len(root) + 1:] for mem in elist] # go through the list of entries and build a map that # maintains a count of how many entries are in each # category elistmap = {} for mem in elist: mem = os.path.dirname(mem) elistmap[mem] = 1 + elistmap.get(mem, 0) self._elistmap = elistmap #print self._elistmap # go through the elistmap keys (which is the list of # categories) and for each piece in the key (i.e. the key # could be "dev/pyblosxom/releases" and the pieces would # be "dev", "pyblosxom", and "releases") we build keys # for the category list map (i.e. "dev", "dev/pyblosxom", # "dev/pyblosxom/releases") clistmap = {} for mem in elistmap.keys(): mem = mem.split(os.sep) for index in range(len(mem) + 1): p = os.sep.join(mem[0:index]) clistmap[p] = 0 # then we take the category list from the clistmap and # sort it alphabetically clist = clistmap.keys() clist.sort() output = [] indent = 0 output.append(start_t) # then we generate each item in the list for item in clist: itemlist = item.split(os.sep) num = 0 for key in self._elistmap.keys(): if item == '' or key == item or key.startswith(item + os.sep): num = num + self._elistmap[key] if not item: tab = "" else: tab = len(itemlist) * " " if indent > len(itemlist): for i in range(indent - len(itemlist)): output.append(end_t) elif indent < len(itemlist): for i in range(len(itemlist) - indent): output.append(begin_t) # now we build the dict with the values for substitution d = { "base_url": self._baseurl, "fullcategory": item + "/", "category": itemlist[-1] + "/", "flavour": flavour, "count": num, "indent": tab } # this prevents a double / in the root category url if item == "": d["fullcategory"] = item #print d # this adds urlencoded versions d["fullcategory_urlencoded"] = tools.urlencode_text( d["fullcategory"]) d["category_urlencoded"] = tools.urlencode_text(d["category"]) # and we toss it in the thing output.append(item_t % d) indent = len(itemlist) output.append(end_t * indent) output.append(finish_t) # export define item's name output[2] = output[2].replace( ">/</a>", " class='rootcategory'>%s/</a>" % rootname) return "\n".join(output)
def test_ampersand_to_26(self): self.eq_(tools.urlencode_text("a&c"), "a%26c")
def test_space_to_20(self): assert tools.urlencode_text("a c") == "a%20c"
def test_everything_else_unchanged(self): assert tools.urlencode_text(None) == None assert tools.urlencode_text("") == "" assert tools.urlencode_text("abc") == "abc"
def test_ampersand_to_26(self): assert tools.urlencode_text("a&c") == "a%26c"
def test_equals_to_3D(self): assert tools.urlencode_text("a=c") == "a%3Dc"
def test_empty_string_to_empty_string(self): assert tools.urlencode_text("") == ""
def test_empty_string_to_empty_string(self): self.eq_(tools.urlencode_text(""), "")
def test_equals_to_3D(self): self.eq_(tools.urlencode_text("a=c"), "a%3Dc")
def test_space_to_20(self): self.eq_(tools.urlencode_text("a c"), "a%20c")
def send_email(config, entry, comment, comment_dir, comment_filename): """Send an email to the blog owner on a new comment @param config: configuration as parsed by Pyblosxom @type config: dictionary @param entry: a file entry @type config: dictionary @param comment: comment as generated by read_comments @type comment: dictionary @param comment_dir: the comment directory @type comment_dir: string @param comment_filename: file name of current comment @type comment_filename: string """ import smtplib # import the formatdate function which is in a different # place in Python 2.3 and up. try: from email.Utils import formatdate except ImportError: from rfc822 import formatdate from socket import gethostbyaddr author = escape_smtp_commands(clean_author(comment['author'])) description = escape_smtp_commands(comment['description']) ipaddress = escape_smtp_commands(comment.get('ipaddress', '?')) if 'comment_smtp_from' in config: email = config['comment_smtp_from'] else: email = escape_smtp_commands(clean_author(comment['email'])) try: curl = "%s/%s" % (config['base_url'], tools.urlencode_text(entry['file_path'])) comment_dir = os.path.join(config['comment_dir'], entry['absolute_path']) # create the message message = [] message.append("Name: %s" % author) if 'email' in comment: message.append("Email: %s" % comment['email']) if 'link' in comment: message.append("URL: %s" % comment['link']) try: host_name = gethostbyaddr(ipaddress)[0] message.append("Hostname: %s (%s)" % (host_name, ipaddress)) # FIXME - bare except here--bad! except: message.append("IP: %s" % ipaddress) message.append("Entry URL: %s" % curl) message.append("Comment location: %s" % comment_filename) message.append("\n\n%s" % description) if 'comment_mta_cmd' in config: # set the message headers message.insert(0, "") message.insert(0, "Subject: comment on %s" % curl) message.insert(0, "Date: %s" % formatdate(float(comment['pubDate']))) message.insert(0, "To: %s" % config["comment_smtp_to"]) message.insert(0, "From: %s" % email) body = '\n'.join(message).encode('utf-8') argv = [ config['comment_mta_cmd'], '-s', '"comment on %s"' % curl, config['comment_smtp_to'] ] process = subprocess.Popen(argv, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process.stdin.write(body) process.stdin.close() process.wait() stdout = process.stdout.read() stderr = process.stderr.read() tools.get_logger().debug('Ran MTA command: ' + ' '.join(argv)) tools.get_logger().debug('Received stdout: ' + stdout) tools.get_logger().debug('Received stderr: ' + stderr) # the except clause below will catch this assert stderr == '', stderr else: assert 'comment_smtp_server' in config server = smtplib.SMTP(config['comment_smtp_server']) mimemsg = MIMEText("\n".join(message).encode("utf-8"), 'plain', 'utf-8') # set the message headers mimemsg["From"] = email mimemsg["To"] = config["comment_smtp_to"] mimemsg["Date"] = formatdate(float(comment["pubDate"])) mimemsg["Subject"] = ("comment on %s" % curl) # send the message via smtp server.sendmail(from_addr=email, to_addrs=config['comment_smtp_to'], msg=mimemsg.as_string()) server.quit() except Exception, e: tools.get_logger().error("error sending email: %s" % traceback.format_exception(*sys.exc_info()))
def genCategories(self): config = self._request.getConfiguration() root = config["datadir"] start_t = config.get("category_start", DEFAULT_START) begin_t = config.get("category_begin", DEFAULT_BEGIN) item_t = config.get("category_item", DEFAULT_ITEM) end_t = config.get("category_end", DEFAULT_END) finish_t = config.get("category_finish", DEFAULT_FINISH) self._baseurl = config.get("base_url", "") form = self._request.getForm() flavour = (form.has_key('flav') and form['flav'].value or config.get('default_flavour', 'html')) # build the list of all entries in the datadir elist = tools.Walk(self._request, root) # peel off the root dir from the list of entries elist = [mem[len(root)+1:] for mem in elist] # go through the list of entries and build a map that # maintains a count of how many entries are in each # category elistmap = {} for mem in elist: mem = os.path.dirname(mem) elistmap[mem] = 1 + elistmap.get(mem, 0) self._elistmap = elistmap # go through the elistmap keys (which is the list of # categories) and for each piece in the key (i.e. the key # could be "dev/pyblosxom/releases" and the pieces would # be "dev", "pyblosxom", and "releases") we build keys # for the category list map (i.e. "dev", "dev/pyblosxom", # "dev/pyblosxom/releases") clistmap = {} for mem in elistmap.keys(): mem = mem.split(os.sep) for index in range(len(mem)+1): p = os.sep.join(mem[0:index]) clistmap[p] = 0 # then we take the category list from the clistmap and # sort it alphabetically clist = clistmap.keys() clist.sort() output = [] indent = 0 output.append(start_t) # then we generate each item in the list for item in clist: itemlist = item.split(os.sep) num = 0 for key in self._elistmap.keys(): if item == '' or key == item or key.startswith(item + os.sep): num = num + self._elistmap[key] if not item: tab = "" else: tab = len(itemlist) * " " if indent > len(itemlist): for i in range(indent - len(itemlist)): output.append(end_t) elif indent < len(itemlist): for i in range(len(itemlist) - indent): output.append(begin_t) # now we build the dict with the values for substitution d = { "base_url": self._baseurl, "fullcategory": item + "/", "category": itemlist[-1] + "/", "flavour": flavour, "count": num, "indent": tab } # this prevents a double / in the root category url if item == "": d["fullcategory"] = item # this adds urlencoded versions d["fullcategory_urlencoded"] = tools.urlencode_text(d["fullcategory"]) d["category_urlencoded"] = tools.urlencode_text(d["category"]) # and we toss it in the thing output.append(item_t % d) indent = len(itemlist) output.append(end_t * indent) output.append(finish_t) # then we join the list and that's the final string self._categories = "\n".join(output)
def cb_head(args): req = args["request"] entry = args["entry"] data = req.get_data() config = req.get_configuration() path = config.get("base_url") from Pyblosxom import tools ## Fallback if not configured BREADCRUMB_ITEM = '<a href="%(url)s">%(item)s</a>' BREADCRUMB_SEP = ' > ' BREADCRUMB_FIRST = 'Home' BREADCRUMB_LABELS = {'' : ''} ## Create the first element entry["breadcrumbs"] = config.get("breadcrumb_item", BREADCRUMB_ITEM) % {"item": config.get("breadcrumb_first", BREADCRUMB_FIRST), "url": path } url = "" ## Get the labels for URLs labels = config.get("breadcrumb_labels", BREADCRUMB_LABELS); gap = False # Walk through the Path from pi_bl for item in data["pi_bl"].split("/"): # We only add a breadcrumb if there really is an item if (item != "index."+data["flavour"]) and (len(item)>0):# and (item != config.get("pages_trigger","")) and (item != "tag"): # Create path path += "/" + tools.urlencode_text(item) # Generate URL for the item if item[-len(data["flavour"])-1:] == "."+data["flavour"]: url = path # Remove .flav from item item = item[:-len(data["flavour"])-1] else: url = path + "/index."+data["flavour"] # Check for labels and extract title if item in labels: # We dont want a breadcrumb for this one gap = True else: import string # If we got a page with a single entry, get the title of it instead of the Filename if (data["pi_bl"].split("/")[-1][:-len(data["flavour"])-1] == item): title = True # Let's go through labels and see if we actually want a title label = "" for x in labels: if string.find(path, '/'+x+'/') != -1: # Don't forget the label, if there is one if labels[x][:1] == "0": title = False item = labels[x][2:] + item else: label = labels[x][2:] if title: # Let's try to get the title of this page entry_list = data.get("entry_list", []) if len(entry_list) == 1: item = label + entry_list[0].get("title",item) # And add that breadcrumb if not gap: entry["breadcrumbs"] += config.get("breadcrumb_sep", BREADCRUMB_SEP) entry["breadcrumbs"] += config.get("breadcrumb_item", BREADCRUMB_ITEM) % {"item": item, "url": url} gap = False return args