예제 #1
0
def add_release(root, url, length, version, shortVersion, title, releaseNotes, minOS=None, maxOS=None, signature=None):
    root = E(root)

    firstItem = pq(root.element).find("item:first")
    method = "before"
    if not firstItem.size():
        firstItem = [root.element]
        method = "append"

    c = getattr(E(firstItem[0]), method)

    c(
        E("item").append(
            E("title", title),
            E("sparkle:releaseNotesLink", releaseNotes),
            minOS and E("sparkle:minimumSystemVersion", minOS),
            maxOS and E("sparkle:maximumSystemVersion", maxOS),
            E("pubDate", time.strftime("%a, %d %b %Y %X %z", time.gmtime())),
            E(
                "enclosure",
                url=url,
                length=str(length),
                type="application/octet-stream",
                **(
                    {
                        "sparkle:version": version,
                        "sparkle:dsaSignature": signature
                        and "MCwCFAmB39sazl2xGIxSF8pHBbBh1zBLAhRmawuNanltHMlkCLv6R8OYiDRigQ==",
                        "sparkle:shortVersionString": shortVersion,
                    }
                )
            ),
        )
    )
예제 #2
0
def load_appcast(appcast_file):
    parser = lxml.etree.XMLParser(remove_blank_text=True)
    xml = lxml.etree.parse(appcast_file, parser)
    root = pq(xml.getroot())

    if not root.find("channel").size():
        return None

    return E(root[0])
예제 #3
0
def load_appcast(appcast_file):
    parser = lxml.etree.XMLParser(remove_blank_text=True)
    xml = lxml.etree.parse(appcast_file, parser)
    root = pq(xml.getroot())

    if not root.find("channel").size():
        return None

    return E(root[0])
예제 #4
0
 def add_release(tool):
     options = {"class": "version", "data-version": tool.get("version"), "data-build": tool.get("build_version")}
     date = time.strftime("%B %d{S} %Y at %H:%M").replace("{S}", date_suffix(time.gmtime().tm_mday))
     if minOS:
         options["data-min-os"] = minOS
     if maxOS:
         options["data-max-os"] = maxOS
     
     parent = E(pq(root.element).find(".sparkle-release-notes")[0])
     release = E("div", 
         E("h1", 
             E("span", "Nightly Build %s" % (tool.get("build_version"))),
             E("time", date, datetime="%s" % (time.strftime("%Y-%m-%d")))),
           options)
     
     features = None
     if "features" in release_notes and len(release_notes["features"]):
         features = E("div", {"class": "features"})
         for feature in release_notes["features"]:
             fe = E("div", {"class": "feature"})
             fe.append(E("h3", feature["title"].decode('utf-8)')))
             description_list = E("ul").append(
                 *([E("li", d) for d in feature["description"]])
             )
             
             fe.append(description_list)
             
             features.append(fe)
     
     features and release.append(features)
     
     fixes = None
     if "fixes" in release_notes and len(release_notes["fixes"]):
         fixes = E("div", {"class": "fixes"})
         fixes.append(E("h2", "Bugfixes"))
         
         fixes.append(E("ul").append(
             *([E("li", f) for f in release_notes["fixes"]])
         ))
     
     fixes and release.append(fixes)
     
     parent.prepend(release)
예제 #5
0
def add_release(root,
                url,
                length,
                version,
                shortVersion,
                title,
                releaseNotes,
                minOS=None,
                maxOS=None,
                signature=None):
    root = E(root)

    firstItem = pq(root.element).find("item:first")
    method = "before"
    if not firstItem.size():
        firstItem = [root.element]
        method = "append"

    c = getattr(E(firstItem[0]), method)

    c(
        E("item").append(
            E("title", title), E("sparkle:releaseNotesLink", releaseNotes),
            minOS and E("sparkle:minimumSystemVersion", minOS), maxOS
            and E("sparkle:maximumSystemVersion", maxOS),
            E("pubDate", time.strftime("%a, %d %b %Y %X %z", time.gmtime())),
            E("enclosure",
              url=url,
              length=str(length),
              type="application/octet-stream",
              **({
                  "sparkle:version": version,
                  "sparkle:dsaSignature": signature and
                  "MCwCFAmB39sazl2xGIxSF8pHBbBh1zBLAhRmawuNanltHMlkCLv6R8OYiDRigQ==",
                  "sparkle:shortVersionString": shortVersion
              }))))
예제 #6
0
def convert_markdown_to_release_notes(md_code=None, filename=None):
    if filename:
        md_code = codecs.open(filename, mode="r", encoding="utf8").read()
    elif type(md_code) == types.StringType:
        md_code = md_code.decode("utf8")
    
    html = markdown.markdown(md_code)
    if not html:
        return (None, "Markdown document is empty.")
    
    root = pq("<html>%s</html>" % (html))
    
    # Check if the required elements are available.
    if not root.find("h1").size():
        return (None, "Title is missing! Please check your markdown for a line which looks like this:\n\n"
                      "Title 1\n=======")
    if not root.find("h2").size():
        return (None, "No Features or Bugfixes subtitle found! Please check your Markdown for a line that looks like this.\n\n"
                      "Subtitle\n--------")
    if not root.find("ul").size():
        return (None, "No Lists found! Please check your Markdown for at least one line that looks like this:\n\n"
                      "* Item 1")
    
    # Format seems to be okay.
    # On to converting the markdown to release_notes dict.
    release_notes = {"info": {}}
    
    info = release_notes["info"]
    key = ""
    fixes = []
    i = -1
    
    titles = []
    features = []
    fixes = []
    # First, find the items between two h2 titles (features and fixes.)
    for item in root.find("h1").nextAll():
        item = pq(item)
        
        if item.is_("h2"):
            titles.append({"title": item.text().lower() == "features" and "features" or "fixes",
                           "items": []})
            i += 1
        
        titles[i]["items"].append(item)
    
    for title in titles:
        if title["title"] == "features":
            j = -1
            for item in title["items"]:
                if item.is_("h3"):
                    features.append({
                        "title": item.html().strip(),
                        "description": []})
                    j += 1
                
                if item.is_("ul"):
                    for item in item.children("li"):
                        item = pq(item)
                        features[j]["description"].append("\n".join([x.strip() for x in item.html().split("\n")]))
                
        elif title["title"] == "fixes":
            for item in title["items"]:
                if item.is_("ul"):
                    for item in item.children("li"):
                        item = pq(item)
                        fixes.append("\n".join([x.strip() for x in item.html().split("\n")]))
    
    info["fixes"] = fixes
    info["features"] = features
    
    return (release_notes, None)
예제 #7
0
def main():
    global APPCAST_ROOT

    (options, args) = parse_options()

    infile = None
    if len(args) == 1:
        infile = os.path.realpath(args[0])

    # If a infile is given but no outfile is set,
    # write to infile.
    if not options.outfile and infile:
        options.outfile = infile

    config = options.from_config and tool_config() or options.__dict__

    tool_name = config["name"].lower()

    if options.from_config:
        additional_options_from_config(config, options)
    else:
        config["title"] = "%s Releases" % (config.get("name"))
        config["description"] = None

    if not options.quiet:
        title("%s %s Sparkle appcast.xml" % (infile and "Update" or "Create", config.get("name")))

    channel = None

    if infile:
        APPCAST_ROOT = None
        APPCAST_ROOT = load_appcast(infile)
        channel = pq(APPCAST_ROOT.element).find("channel")[0]

        if not APPCAST_ROOT:
            error("Couldn't load Sparkle appcast.xml file")

    if not infile:
        # Adding the channel info.
        add_channel_info(
            APPCAST_ROOT,
            title=config.get("title"),
            link=config.get("appcast_url"),
            description=config.get("description"),
            image=config.get("appicon_url"),
        )
        channel = pq(APPCAST_ROOT.element).find("channel")[0]

    if options.from_config:
        filesize = config["filesize"]
    else:
        filesize = options.filesize

    # Adding the release item.
    if not options.quiet:
        status("Adding release info of %s v%s" % (config["name"], config.get("version")))

    # If replace is set, remove all releases first.
    if options.replace:
        pq(channel).find("item").remove()

    add_release(
        channel,
        url=config.get("url"),
        length=filesize,
        version=config.get("build_version"),
        shortVersion=config.get("version"),
        title="%s v%s"
        % (config.get("name"), config.get("version").replace(")", " build %s)" % config.get("build_version"))),
        releaseNotes=config.get("release_notes_url"),
        minOS=config.get("minOS"),
        maxOS=config.get("maxOS"),
    )

    xml = APPCAST_ROOT.xml(**XML_PRINT_CONFIG)

    if options.outfile:
        with open(options.outfile, "w") as fp:
            fp.write(xml)
    else:
        print xml

    if not options.quiet:
        success("Sparkle appcast.xml file was successfully %s" % (infile and "updated" or "created"))

    return True
예제 #8
0
def main():
    global APPCAST_ROOT

    (options, args) = parse_options()

    infile = None
    if len(args) == 1:
        infile = os.path.realpath(args[0])

    # If a infile is given but no outfile is set,
    # write to infile.
    if not options.outfile and infile:
        options.outfile = infile

    config = options.from_config and tool_config() or options.__dict__

    tool_name = config["name"].lower()

    if options.from_config:
        additional_options_from_config(config, options)
    else:
        config["title"] = "%s Releases" % (config.get("name"))
        config["description"] = None

    if not options.quiet:
        title("%s %s Sparkle appcast.xml" %
              (infile and "Update" or "Create", config.get("name")))

    channel = None

    if infile:
        APPCAST_ROOT = None
        APPCAST_ROOT = load_appcast(infile)
        channel = pq(APPCAST_ROOT.element).find("channel")[0]

        if not APPCAST_ROOT:
            error("Couldn't load Sparkle appcast.xml file")

    if not infile:
        # Adding the channel info.
        add_channel_info(APPCAST_ROOT,
                         title=config.get("title"),
                         link=config.get("appcast_url"),
                         description=config.get("description"),
                         image=config.get("appicon_url"))
        channel = pq(APPCAST_ROOT.element).find("channel")[0]

    if options.from_config:
        filesize = config["filesize"]
    else:
        filesize = options.filesize

    # Adding the release item.
    if not options.quiet:
        status("Adding release info of %s v%s" %
               (config["name"], config.get("version")))

    # If replace is set, remove all releases first.
    if options.replace:
        pq(channel).find("item").remove()

    add_release(channel,
                url=config.get("url"),
                length=filesize,
                version=config.get("build_version"),
                shortVersion=config.get("version"),
                title="%s v%s" %
                (config.get("name"), config.get("version").replace(
                    ")", " build %s)" % config.get("build_version"))),
                releaseNotes=config.get("release_notes_url"),
                minOS=config.get("minOS"),
                maxOS=config.get("maxOS"))

    xml = APPCAST_ROOT.xml(**XML_PRINT_CONFIG)

    if options.outfile:
        with open(options.outfile, "w") as fp:
            fp.write(xml)
    else:
        print xml

    if not options.quiet:
        success("Sparkle appcast.xml file was successfully %s" %
                (infile and "updated" or "created"))

    return True
예제 #9
0
def convert_markdown_to_release_notes(md_code=None, filename=None):
    if filename:
        md_code = codecs.open(filename, mode="r", encoding="utf8").read()
    elif type(md_code) == types.StringType:
        md_code = md_code.decode("utf8")

    html = markdown.markdown(md_code)
    if not html:
        return (None, "Markdown document is empty.")

    root = pq("<html>%s</html>" % (html))

    # Check if the required elements are available.
    if not root.find("h1").size():
        return (
            None,
            "Title is missing! Please check your markdown for a line which looks like this:\n\n"
            "Title 1\n=======")
    if not root.find("h2").size():
        return (
            None,
            "No Features or Bugfixes subtitle found! Please check your Markdown for a line that looks like this.\n\n"
            "Subtitle\n--------")
    if not root.find("ul").size():
        return (
            None,
            "No Lists found! Please check your Markdown for at least one line that looks like this:\n\n"
            "* Item 1")

    # Format seems to be okay.
    # On to converting the markdown to release_notes dict.
    release_notes = {"info": {}}

    info = release_notes["info"]
    key = ""
    fixes = []
    i = -1

    titles = []
    features = []
    fixes = []
    # First, find the items between two h2 titles (features and fixes.)
    for item in root.find("h1").nextAll():
        item = pq(item)

        if item.is_("h2"):
            titles.append({
                "title":
                item.text().lower() == "features" and "features" or "fixes",
                "items": []
            })
            i += 1

        titles[i]["items"].append(item)

    for title in titles:
        if title["title"] == "features":
            j = -1
            for item in title["items"]:
                if item.is_("h3"):
                    features.append({
                        "title": item.html().strip(),
                        "description": []
                    })
                    j += 1

                if item.is_("ul"):
                    for item in item.children("li"):
                        item = pq(item)
                        features[j]["description"].append("\n".join(
                            [x.strip() for x in item.html().split("\n")]))

        elif title["title"] == "fixes":
            for item in title["items"]:
                if item.is_("ul"):
                    for item in item.children("li"):
                        item = pq(item)
                        fixes.append("\n".join(
                            [x.strip() for x in item.html().split("\n")]))

    info["fixes"] = fixes
    info["features"] = features

    return (release_notes, None)