From 0447911e547df3c960a25e603cc4e062d44aeac6 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Thu, 14 Oct 2010 17:04:22 -0400 Subject: [PATCH] We're generating what looks like well-formed JSON. --- freshmeat-submit | 96 ++++++++++++++------------- freshmeat-submit.xml | 151 ++++++++++--------------------------------- 2 files changed, 84 insertions(+), 163 deletions(-) diff --git a/freshmeat-submit b/freshmeat-submit index b0d1fa6..a802463 100755 --- a/freshmeat-submit +++ b/freshmeat-submit @@ -49,26 +49,27 @@ class FreshmeatSession: "Withdraw a specified release from the current project." pass +focus_values = ( + "Initial freshmeat announcement", + "Documentation", + "Code cleanup", + "Minor feature enhancements", + "Major feature enhancements" + "Minor bugfixes", + "Major bugfixes", + "Minor security fixes", + "Major security fixes", +) + +# Note: Release Focus is no longer a real Freshmeat field; we'll remap it later. freshmeat_field_map = ( - ("Project", "p", "project_name"), + ("Project", "p", "name"), ("Version", "v", "version"), ("Changes", "c", "changelog"), ("Hide", "x", "hide_from_frontpage"), - ("License", "l", "license"), - ("Home-Page-URL", "H", "url_homepage"), - ("Gzipped-Tar-URL", "G", "url_tgz"), - ("Bzipped-Tar-URL", "B", "url_bz2"), - ("Zipped-Tar-URL", "Z", "url_zip"), - ("Changelog-URL", "C", "url_changelog"), - ("RPM-URL", "R", "url_rpm"), - ("Debian-URL", "D", "url_deb"), - ("OSX-URL", "O", "url_osx"), - ("BSD-Port-URL", "P", "url_bsdport"), - ("Purchase-URL", "U", "url_purchase"), - ("CVS-URL", "S", "url_cvs"), - ("Mailing-List-URL", "L", "url_list"), - ("Mirror-Site-URL", "M", "url_mirror"), - ("Demo-URL", "E", "url_demo"), + ("Release-Focus", "r", "release_focus"), + ("Tag-List", "t", "tag_list"), + ("License-List", "l", "license_list"), ) def get_rpm_field(fld, rpm): @@ -78,35 +79,35 @@ def get_rpm_field(fld, rpm): raise ValueError return output -def crack_rpm(rpm, dict): +def crack_rpm(rpm, meta, urls): "Extract freshmeat metadata from an RPM." try: # Some fields can be copied literally if present. - if not "project_name" in dict: - dict["project_name"] = get_rpm_field("name", rpm) - if not "version" in dict: - dict["version"] = get_rpm_field("version", rpm) + if not "name" in meta: + meta["name"] = get_rpm_field("name", rpm) + if not "version" in meta: + meta["version"] = get_rpm_field("version", rpm) # This doesn't work. The values don't map over. - #if not "license" in dict: - # dict["license"] = get_rpm_field("license", rpm) - if not "url_homepage" in dict: - dict["url_homepage"] = get_rpm_field("url", rpm) - if not "changes" in dict: + #if not "license" in meta: + # meta["license"] = get_rpm_field("license", rpm) + if not "url_homepage" in meta: + meta["url_homepage"] = get_rpm_field("url", rpm) + if not "changes" in meta: # Querying gets you the first entry, apparently # blank-line-delimited. changes = get_rpm_field("changelogtext", rpm) # Canonicalize, stripping leading spaces. changes = map(lambda x: x.strip(), changes.split('\n')) changes = "\n".join(changes) + "\n" - dict["changes"] = changes + meta["changelog"] = changes # RPMs have a source field; figure out which Freshmeat field it maps to source = get_rpm_field("source", rpm) if source.endswith(".tar.gz") or source.endswith(".tgz"): - if "url_tgz" not in dict: - dict["url_tgz"] = source + if "Tar/GZ" not in urls: + urls["Tar/GZ"] = source if source.endswith(".tar.bz2"): - if "url_bz2" not in dict: - dict["url_bz2"] = source + if "Tar/BZ" not in urls: + urls["Tar/BZ"] = source except ValueError: pass @@ -143,18 +144,22 @@ class FreshmeatMetadataFactory: raise FreshmeatSessionException("Illegal field name %s" % hdr) def getMetadata(self, stream): - "Make a Metadata object." + "Make a JSON-like Python object describing an update." data = {} + urls = {} (options, args) = self.argument_parser.parse_args() - # First stuff from rpms if present. + # First stuff from RPMs if present. for file in args: if file.endswith(".rpm"): - crack_rpm(file, data) - # Second. stuff fropm stdin if present + crack_rpm(file, data, urls) + # Second. stuff from stdin if present if options.read: message = self.message_parser.parse(stream) for (key, value) in message.items(): - data.update({self.header_to_field(key) : value}) + if key.endswith("-URL"): + urls.update({key[:-4] : value}) + else: + data.update({self.header_to_field(key) : value}) if not 'changes' in data: data['changes'] = message.get_payload() # Merge in options from the command line; @@ -163,11 +168,16 @@ class FreshmeatMetadataFactory: for (key, value) in options.__dict__.items(): if key != 'read' and value != None: data[key] = value - # Release-Focus field may have to be validated later. + # Release-Focus field special handling if "release_focus" in data: - val = data["release_focus"].lower() - if val in '123456789': - data["release_focus"] = int(val) + if data["release_focus"] in '123456789': + data["release_focus"] = focus_values[int(data["release_focus"])-1] + if data["release_focus"] not in focus_values: + raise FreshmeatSessionException("Invalid release focus") + data["tag_list"] = data["release_focus" ] + del data["release_focus"] + # Now merge in the URLs + data['approved_urls'] = map(lambda (k, v): {"label": k, "url": v}, urls.items()) return data if __name__ == "__main__": @@ -182,11 +192,7 @@ if __name__ == "__main__": noemit = data['noemit']; del data['noemit'] # Maybe we just want to sanity-check the send if noemit or verbose: - for (field, shortopt, key) in freshmeat_field_map: - if key in data and key != 'changes': - print "%s: %s" % (field, data[key]) - if 'changes' in data: - sys.stdout.write("\n" + data['changes']) + print data # Time to ship the update. if not noemit: # Establish session diff --git a/freshmeat-submit.xml b/freshmeat-submit.xml index f5c5e27..5cb341c 100644 --- a/freshmeat-submit.xml +++ b/freshmeat-submit.xml @@ -99,7 +99,7 @@ present) becomes the change announcement text. -Here is a table of the fields and their +Here is a table of metadata fields and their corresponding command-line switches: @@ -165,131 +165,33 @@ release will not be visible on the project page. License: - -l--license -Specify the license under which the release is issued. Note -that this is not copied from the RPM License field, because the -values don't map. +Specify the licenses under which the release is issued. This +may be a comma-reparated list. Note that this is not copied from the +RPM License field, because the values don't map. -Home-Page-URL: URL +Website-URL: URL -H--home-page-url Specify the project home page. -Gzipped-Tar-URL: SOURCE +Tar/GZ-URL: SOURCE -G--gzipped-tar-url Specify the URL where a gzipped tarball of source can be found. - -Bzipped-Tar-URL: SOURCE --B--bzipped-tar-url - -Specify the URL where a bzipped tarball of source can be found. - - - - -Zipped-Tar-URL: - --Z--zipped-tar-url - -Specify the URL where a zipped tarball of source can be found. - - - - -Changelog-URL: - --C--changelog-url - -Specify the URL where the project changelog can be found. - - - - -RPM-URL: - --R--rpm-url - -Specify the URL where an installable binary RPM can be found. - - - - -Debian-URL: - --D--debian-url - -Specify the URL where an installable Debian package can be found. - - - - -OSX-URL: - --O--osx-url - -Specify the URL where an OS/X binary can be found. - - - - -BSD-Port-URL: - --P--bsdport-url - -Specify the URL where a BSD Ports package can be found. - - - - -Purchase-URL: - --U--purchase-url - -Specify the URL where the software can be purchased. - - - - -CVS-URL: - --S--cvs-url - -Specify the URL of the CVS for this package. - - - - -Mailing-List-URL: - --L--mailing-list-url - -Specify the URL where you can sign up for project mailing lists. - - - - -Mirror-Site-URL: - --M--mirror-site-url - -Specify the URL where an official mirror site for the project -can be found. - - - - -Demo-URL: - --Eurl-demo - -Specify the URL where a demonstration site for the package -can be found. - - - -The license and all URL fields, when specified, actually change -the branch record for the project. Only the Changes, Version, +The License-List and all URL fields, when specified, actually change +the record for the project. Only the Changes, Version, Release-Focus, and Hide fields are actually stored for each version. @@ -323,9 +225,8 @@ Project: doclifter Version: 1.1 Release-Focus: Major feature enhancements Hide: N -Home-Page-URL: http://www.catb.org/~esr/doclifter/ -Gzipped-Tar-URL: http://www.catb.org/~esr/doclifter/doclifter-1.1.tar.gz -RPM-URL: http://www.catb.org/~esr/doclifter/doclifter-1.1-1.i386.rpm +Website-URL: http://www.catb.org/~esr/doclifter/ +Tar/GZ-URL: http://www.catb.org/~esr/doclifter/doclifter-1.1.tar.gz Fixed a bug in conditional evaluation that twadmin(8) tickled. Better detection of pure inclusions. Better blank-section elimination. @@ -338,11 +239,11 @@ version lifts 96% of 9829 manual pages in a full Red Hat 9 installation with Fedora updates to *validated* XML-DocBook. -More typically, you will run this program in a directory where -you have already made an RPM, giving it the RPM as a file argument. -In that case, all you will normally need to supply is the Release-Focus -field; the other required fields (including, most notably, the Changes -field) will be mined out of the RPM. +You may run this program in a directory where you have already +made an RPM, giving it the RPM as a file argument. In that case, all +you will normally need to supply is the Release-Focus field; the other +required fields (including, most notably, the Changes field) will be +mined out of the RPM. WARNING @@ -351,6 +252,21 @@ data API significantly. While we have attempted to maintain backward compatibility, the data model has changed in significant ways. There is no longer a Branch attribute. + +The old Release-Focus field is gone. As a special case, this +pragram will validate it and use it to fill in the tags list. + +The old License field is now License-List and can take a +comma-separated list of licenses. + +The old Home-Page-URL is noe Website-URL to match the convention +used by the new API. + +The old Gzipped-Tar-URL is now Tar/GZ-URL to match the convention +used by the new API. + +All the other special-case URL fields are gone. They're replaced by +the general mechanism for pairing URLs with labels. FILES @@ -360,13 +276,12 @@ compatibility, the data model has changed in significant ways. ~/.netrc freshmeat-submit expects to find your -Freshmeat credentials here. The correct form for an entry looks like +Freshmeat authorization tag here. The correct form for an entry looks like this: machine freshmeat - login <your_freshmeat_login> - password <your_freshmeat_password> + account <your_api_auth_code> For security, make sure your ~/.netrc file @@ -380,7 +295,7 @@ is not world-readable; we recommend doing chmod 600 RETURN VALUES 0 on success, 1 on failure. In case of failure, any error message -passed back by the XML-RPC interface is issued to standard error. +passed back by the Freshmeat API is issued to standard error. AUTHORS -- 2.43.0