freecode-submit-2.7/freecode-submit0000775000175000017500000004300612256273046015622 0ustar esresr#!/usr/bin/env python """ freecode-submit -- script transactions with the Freecode server """ import sys, re, urllib2, json, netrc, email.Parser, optparse version = "2.7" class Update: "Encapsulate dictionaries describing a project metadata update." def __init__(self): self.name = None self.per_project = {} self.urlassoc = [] self.per_release = {} def __repr__(self): return "Update(" + repr(self.__dict__) + ")" # The Freecode API implementation is sensitive to the kind of HTTP request # method you use. The general rule is: # # Reading records: GET # Adding new records: POST # Updating existing records: PUT # Deleting existing records: DELETE # # From http://help.freecode.com/faqs/api-7/data-api-intro: # 200 OK - Request was successful, the requested content is included # 201 Created - Creation of a new resource was successful # 401 Unauthorized - You need to provide an authentication code with this # request # 403 Forbidden - You don't have permission to access this URI # 404 Not Found - The requested resource was not found # 409 Conflict - The validation of your submitted data failed, please check # the response body for error pointers # 500 Server Error - The request hit a problem and was aborted, please report # as a bug if it persists # 503 Service Unavailable - You hit your API credit limit class RequestWithMethod(urllib2.Request): "Hack for forcing the method in a request - allows PUT and DELETE" def __init__(self, method, *args, **kwargs): # This assignment works directly in older Python versions self._method = method urllib2.Request.__init__(self, *args, **kwargs) def get_method(self): "Deduce the HTTP method to use." # This method works in newer Pythons (2.6.5, possibly earlier). if self._method: return self._method elif self.has_data(): return "POST" else: return "GET" class FreecodeSessionException(Exception): "Carry exception state when a session blows up." def __init__(self, msg): Exception.__init__(self) self.msg = msg class FreecodeSession: "Encapsulate the state of a Freecode API session." server = "https://freecode.com/" def __init__(self, auth=None, verbose=0, emit_enable=True): "Initialize Freecode session credentials." self.auth = auth self.verbose = verbose self.emit_enable = emit_enable self.project = None self.permalink = None self.id = None self.project_data = None # If user didn't supply credentials, fetch from ~/.netrc if not self.auth: try: credentials = netrc.netrc() except netrc.NetrcParseError, e: raise FreecodeSessionException("ill-formed .netrc: %s:%s %s" \ % (e.filename, e.lineno, e.msg)) except IOError, e: raise FreecodeSessionException(("missing .netrc file %s" % \ str(e).split()[-1])) ret = credentials.authenticators("freecode") if not ret: raise FreecodeSessionException("no credentials for Freecode") _login, self.auth, _password = ret def on_project(self, name): "Select project by Freecode shortname." if self.verbose: print "Selecting project: %s" % name self.project = name pquery = FreecodeSession.server + "projects/%s.json?auth_code=%s" \ % (self.project, self.auth) handle = urllib2.urlopen(pquery) content = json.loads(handle.read()) self.project_data = content['project'] #if self.verbose: # print "Project data: %s" % self.project_data self.permalink = self.project_data['permalink'] self.id = self.project_data['id'] def edit_request(self, url, method="GET", request=None, force=False): "Wrap a JSON object with the auth code and ship it as a request" if request is None: request = {} url = FreecodeSession.server + url data = {"auth_code" : self.auth} data.update(request) data = json.dumps(data) headers = {"Content-Type" : "application/json"} if self.verbose: print "Request URL:", method, url #if self.verbose: # print "Request headers:", headers if self.verbose: print "Request data:", data if self.emit_enable or force: req = RequestWithMethod(method=method, url=url, data=data, headers=headers) handle = urllib2.urlopen(req) if self.verbose: print handle.info() content = handle.read() if self.verbose: print "Response:", content return content def publish_release(self, data): "Add a new release to the current project." if self.verbose: print "Publishing %s release: %s" % (self.project, repr(data)) self.edit_request("projects/" + self.permalink + "/releases.json", "POST", {"release": data}) def withdraw_release(self, dversion): "Withdraw a specified release from the current project." if self.verbose: print "Withdrawing %s release: %s" % (self.project, dversion) releases = self.edit_request("projects/%s/releases/pending.json" \ % self.permalink, force=True) releases = json.loads(releases) for release in releases: properties = release["release"] if properties.get("version") == dversion: vid = properties["id"] break else: raise FreecodeSessionException("couldn't find release %s"%dversion) deletelink = "projects/%s/releases/%s.json" % (self.permalink, vid) self.edit_request(deletelink, "DELETE", {}) def update_core(self, coredata): "Update the core data for a project." if self.verbose: print "Core data update for %s is: %s" % (self.project, coredata) self.edit_request("projects/" + self.permalink + ".json", "PUT", {"project": coredata}) def update_urls(self, urlassoc): "Update URL list for a project." if self.verbose: print "URL list update for %s is: %s" % (self.project, urlassoc) # First, get permalinks for all existing URLs uquery = FreecodeSession.server + "projects/%s/urls.json?auth_code=%s" \ % (self.permalink, self.auth) handle = urllib2.urlopen(uquery) content = json.loads(handle.read()) permadict = {} for item in content: inner = item['url'] permadict[inner['label']] = inner['permalink'] # OK, now run through the update list... for (label, url) in urlassoc: if label in permadict: # updating where we need to self.edit_request("projects/%s/urls/%s.json" % (self.permalink, permadict[label]), "PUT", {"url" : {"label": label, "location" : url}}) else: # and adding where we don't. self.edit_request("projects/%s/urls.json" % (self.permalink,), "POST", {"url" : {"label": label, "location" : url}}) # Delete URLs that weren't in the update list remove = set(permadict.keys()) - set(map(lambda x: x[0], urlassoc)) for label in remove: self.edit_request("projects/%s/urls/%s.json?auth_code=%s" % (self.permalink, permadict[label], self.auth), "DELETE", {}) class FreecodeMetadataFactory: "Factory class for producing Freecode records in JSON." freecode_field_map = ( ("Project", "P", "name"), # Project ("Summary", "S", "oneliner"), # Project ("Description", "D", "description"), # Project ("License-List", "L", "license_list"), # Project ("Project-Tag-List", "T", "project_tag_list"), # Project ("Version", "v", "version"), # Release ("Changes", "c", "changelog"), # Release ("Hide", "x", "hidden_from_frontpage"), # Release ("Release-Tag-List", "t", "tag_list"), # Release ) # Which attributes have project scope, all others have release scupe projectwide = ('name', 'description', 'oneliner', 'license_list', 'project_tag_list') def __init__(self): self.message_parser = email.Parser.Parser() self.argument_parser = optparse.OptionParser( \ usage="usage: %prog [options]") for (msg_field, shortopt, rpc_field) in FreecodeMetadataFactory.freecode_field_map: self.argument_parser.add_option("-" + shortopt, "--" + msg_field.lower(), dest=rpc_field, help="Set the %s field"%msg_field) self.argument_parser.add_option('-q', '--query', dest='query', help='Query metadata for PROJECT',metavar="PROJECT") self.argument_parser.add_option('-d', '--delete', dest='delete', default=False, action='store_true', help='Suppress reading fields from stdin.') self.argument_parser.add_option('-n', '--no-stdin', dest='read', default=True, action='store_false', help='Suppress reading fields from stdin.') self.argument_parser.add_option('-N', '--dryrun', dest='dryrun', default=False, action='store_true', help='Suppress reading fields from stdin.') self.argument_parser.add_option('-V', '--verbose', dest='verbose', default=False, action='store_true', help='Enable verbose debugging.') self.argument_parser.add_option('-?', '--showversion', dest='showversion', default=False, action='store_true', help='Show version and quit.') @staticmethod def header_to_field(hdr): "Map a header name from the job card format to a field." lhdr = hdr.lower().replace("-", "_") for (alias, _shortopt, field) in FreecodeMetadataFactory.freecode_field_map: if lhdr == alias.lower().replace("-", "_").replace("/", "_"): return field raise FreecodeSessionException("Illegal field name %s" % hdr) def getMetadata(self, stream): "Return an Update object describing project and release attributes." data = {} urls = {} (options, _args) = self.argument_parser.parse_args() # Stuff from stdin if present prior_version = data.get("version") if not (options.query or options.showversion) and options.read: message = self.message_parser.parse(stream) for (key, value) in message.items(): value = re.sub("\n +", " ", value).strip() if key.endswith("-URL"): key = key.replace("-", " ") urls.update({key[:-4] : value}) else: if key.endswith("List"): value = map(lambda x: x.strip(), value.split()) data.update({FreecodeMetadataFactory.header_to_field(key) : value}) if not 'changelog' in data: payload = message.get_payload().strip() if payload: data['changelog'] = payload + "\n" if prior_version and data.get("version") != prior_version: raise FreecodeSessionException("Version conflict on stdin.") # Merge in options from the command line; # they override what's on stdin. controls = ('query', 'delete', 'read', 'dryrun', 'verbose', 'showversion') prior_version = data.get("version") for (key, value) in options.__dict__.items(): if key not in controls and value != None: data[key] = value del options.__dict__[key] if prior_version and data.get("version") != prior_version and not options.delete: raise FreecodeSessionException("Version conflict in options.") # Hidden flag special handling if "hidden_from_frontpage" in data: data["hidden_from_frontpage"] = data["hidden_from_frontpage"] in ("Y", "y") # Now merge in the URLs, doing symbol substitution urllist = [] for (label, furl) in urls.items(): for (k, v) in data.items(): if type(v) == type(""): furl = furl.replace('${' + k + '}', v) urllist.append((label, furl)) # Sort out what things go where update = Update() if options.showversion: pass elif options.query: update.name = options.query else: update.name = data.pop('name') update.urlassoc = urllist for (k, v) in data.items(): if k in FreecodeMetadataFactory.projectwide: # Hack to get around a namespace collision if k == "project_release_tag": k = "release_tag" update.per_project[k] = v else: update.per_release[k] = v # Return this return (options, update) if __name__ == "__main__": try: # First, gather update data from stdin and command-line switches factory = FreecodeMetadataFactory() (options, update) = factory.getMetadata(sys.stdin) # Some switches shouldn't be passed to the server query = 'query' in options.__dict__ and options.query verbose = 'verbose' in options.__dict__ and options.verbose delete = 'delete' in options.__dict__ and options.delete dryrun = 'dryrun' in options.__dict__ and options.dryrun showversion = 'showversion' in options.__dict__ and options.showversion if showversion: print "freecode-submit", version raise SystemExit, 0 # Time to ship the update. # Establish session session = FreecodeSession(verbose=int(verbose), emit_enable=not dryrun) try: session.on_project(update.name) except ValueError, e: print e print >>sys.stderr, "freecode-submit: looks like a server-side problem at freecode; bailing out." raise SystemExit, 1 if options.query: print "Project: %s" % session.project_data["name"] print "Summary: %s" % session.project_data["oneliner"] print "Description: %s" % session.project_data["description"].replace("\n", "\n ").rstrip() print "License-List: %s" % ",".join(session.project_data["license_list"]) print "Project-Tag-List: %s" % ",".join(session.project_data["tag_list"]) for assoc in session.project_data['approved_urls']: #print "Querying", assoc["redirector"] #req = RequestWithMethod(method="HEAD", # url=assoc["redirector"], # data={}, # headers={}) #handle = urllib2.urlopen(req) #print "===" #print handle.info() #print "===" print "%s-URL: %s" % (assoc["label"].replace(" ","-"), assoc["redirector"]) if 'recent_releases' in session.project_data and session.project_data['recent_releases']: most_recent = session.project_data['recent_releases'][0] print "Version: %s" % most_recent['version'] print "Tag-List: %s" % ",".join(most_recent['tag_list']) if most_recent.get('hidden_from_frontpage'): print "Hide: Y" else: print "Hide: N" print "" print most_recent["changelog"] else: # OK, now actually add or delete the release. if update.per_project: session.update_core(update.per_project) if update.urlassoc: session.update_urls(update.urlassoc) if delete: session.withdraw_release(update.per_release['version']) elif update.per_release and update.per_release.keys()!=["version"]: session.publish_release(update.per_release) except FreecodeSessionException, e: print >>sys.stderr,"freecode-submit:", e.msg sys.exit(1) except urllib2.HTTPError, f: print >>sys.stderr,"freecode-submit: HTTPError %s" % (f.code) print >>sys.stderr,f.read() sys.exit(1) except urllib2.URLError, f: print >>sys.stderr,"freecode-submit: URLError %s" % (f.reason,) print >>sys.stderr,f.read() sys.exit(1) # end freecode-submit-2.7/README0000644000175000017500000000051711761255503013473 0ustar esresr freecode-submit freecode-submit is a script that supports remote submission of release updates to Freecode via its JSON interface. It is intended for use in project release scripts. (This project was formerly called freshmeat-submit. It changed its name in 2011 when Freecode did.) Eric S. Raymond December 2003 freecode-submit-2.7/AUTHORS0000644000175000017500000000004207767543742013674 0ustar esresrEric S. Raymond freecode-submit-2.7/freecode-submit.xml0000644000175000017500000002613312227607367016423 0ustar esresr freecode-submit 1 freecode-submit Development Tools Oct 17 2010 freecode-submit submit release announcements and project metadata updates to freecode.com freecode-submit -q -V -n -N -d --showversion data-options data-options DESCRIPTION freecode-submit is a command-line tool for submitting release announcements to freecode.com. It is intended for batch-mode operation in project release scripts, and designed so that its input format can easily be generated by scripts. freecode-submit accepts release information from a job card (an email-message-like data block on standard input) or from command-line flags. Values set with command-line flags override those collected from the job card. The accumulated data is entered into the freecode database via its API. A few flags control the operation of freecode-submit itself. -q, --query Query the specified project. Delivers to standard output a job card describing the project metadata that can be edited and fed back to this tool. The data with release rather than project scope is for the most recent release. -d, --delete Delete the specified release rather than submitting it. With this option, all data other than Project and Release are ignored. Note: only works if the release has been submitted but not yet passed by a moderator; if the release is already posted, invoking this mode will throw an error. -n, --no-stdin Process command-line options only; don't read data from standard input. -N, --dryrun Generate JSON, but don't ship any modification requests to Freecode. Useful for debugging in combination with -V. Note, this mode may generate requests which read data from Freecode in order to get permalink data. -V, --verbose Enable verbose debugging of the transaction. This option is mainly for developers. --showversion Show the version of this program and exit. Release information is accepted from sources in the following order: An RFC-2822-format job card, strongly resembling an ordinary email message, on standard input. The message header fields each specify a particular item of release information; the body (if present) becomes the change announcement text. Within URL fields, the string ${version} will be replaced with the contents of the Version field. Command-line switches. Here is a table of metadata fields and their corresponding command-line switches: Message field Scope Short switch Long switch Explanation Project: Project -P--project Name of the project (freecode shortname) to operate on. You cannot change the project-name attribute with this program; to do that, you need to use the Freecode web interface. Summary: Project -S--summary One-line summary of the project. Description: Project -D--description Multiline description of the project. (Use RFC-822-style continuation lines) License-List: Project -L--license-list Specify the licenses under which the project is issued. This may be a comma-separated list. Project-Tag-List:Release -T--project-tag-list Tags to attach to this project. May be a comma-separated list. Version: Release -v--version Version string to be associated with the release. Changes: Release -c--changes The Changes field. If no Changes field or option is already present, the changes text is taken from the body of the RFC-822 message on standard input. Release-Tag-List: Release -t--tag-list Tags to attach to this release. May be a comma-separated list. Hide: Release -x--hide If this field is present and has the value “Y”, this release will not be visible on the project page. Additionally, you can specify tagged URL fields for the Freecode project record with header lines ending in "-URL:". The tag will be the header with the "-URL:" suffix stripped off. Some examples of how to set frequently-used URL types: Message field Tag Usage Website-URL: Website Project website home page. If you specify this, it will be used to activate the "More Information" link and Home icon on the project page. Download-URL: Download Preferred download URL. If you specify this, it will be used to activate the "Download" link and floppy-disk icon on the project page. Tar/GZ-URL: Tar/GZ tar archive compressed with gzip Tar/BZ-URL: Tar/BZ tar archive compressed with bzip Changelog-URL Changelog project change log Note that the list of URLs you ship does not merely add to the existing list but overwrites it - that is how you delete old URLs which are no longer valid. The Summary, Description, License-List, Project-Tag-List and all URL fields, when specified, actually change the record for the project. Only the Tag-List, Changes, Version, and Hide fields are actually stored for each version. The following elements of Freecode project metadata cannot yet be modified using this tool: name, translation list, programming language list, operating system list, approved screenshots, and dependency records. Support for updating all these elements except name is planned in future releases. USAGE Here is an example of a release-information record that could be fed to freecode-submit on standard input: Project: doclifter Version: 1.1 Hide: N Website-URL: http://www.catb.org/~esr/doclifter/ Tar/GZ-URL: http://www.catb.org/~esr/doclifter/doclifter-${version}.tar.gz Fixed a bug in conditional evaluation that twadmin(8) tickled. Better detection of pure inclusions. Better blank-section elimination. Kleene star recognized as ... synonym in command synopses. Correct some bugs in semantic-hint collection. Recognize Qt manual pages and use their conventions. Better lifting of mandoc-generated pages. Translate groff-style \[...] escapes, flag unknown ones. Can now parse K&R style function prototypes as well as ANSI ones. This version lifts 96% of 9829 manual pages in a full Red Hat 9 installation with Fedora updates to *validated* XML-DocBook. WARNING Since this program was first written, Freecode has changed its data API significantly (and its name, too; it used to be 'Freshmeat'). 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. The old License field is now License-List and can take a comma-separated list of licenses. All the old URL fields are gone. They're replaced by the general mechanism for pairing URLs with labels. Earlier versions parsed RPM specfiles. This was poor separation of function and has been removed. That responsibility belongs to the human or program generating the job card. FILES ~/.netrc freecode-submit expects to find your Freecode authorization tag here. The correct form for an entry looks like this: machine freecode account <your_api_auth_code> password none For security, make sure your ~/.netrc file is not world-readable; we recommend doing chmod 600 ~/.netrc. BUGS The URLs returned in a project metadata query are Freecode redirectors, not the actual URLS supplied by previous project updates. This is due to a limitation in the Freecode API which may be fixed in future versions of that API. RETURN VALUES 0 on success, 1 on failure. In case of failure, any error message passed back by the Freecode API is issued to standard error. AUTHORS Eric S. Raymond esr@thyrsus.com. freecode-submit-2.7/COPYING0000644000175000017500000000261511457316766013662 0ustar esresr BSD LICENSE Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither name of the this project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. freecode-submit-2.7/Makefile0000664000175000017500000000346512243267225014262 0ustar esresr# Makefile for the freecode-submit tool VERS=$(shell sed MANIFEST (cd ..; ln -s freecode-submit freecode-submit-$(VERS)) (cd ..; tar -czf freecode-submit/freecode-submit-$(VERS).tar.gz `cat freecode-submit/MANIFEST`) (cd ..; rm freecode-submit-$(VERS)) freecode-submit-$(VERS).md5: freecode-submit-$(VERS).tar.gz @md5sum freecode-submit-$(VERS).tar.gz >freecode-submit-$(VERS).md5 pychecker: @ln -f freecode-submit freecode-submit.py @-pychecker --only --limit 50 freecode-submit.py @rm -f freecode-submit.py PYLINTOPTS = --rcfile=/dev/null --reports=n --include-ids=y --disable="C0103,C0301,C0323,R0903,R0912,R0914,W0141,W0621,F0401,E0611,E1101" pylint: @pylint --output-format=parseable $(PYLINTOPTS) freecode-submit clean: rm -f *.pyc *.html freecode-submit.1 MANIFEST ChangeLog *~ rm -f *.tar.gz *.md5 dist: freecode-submit-$(VERS).tar.gz release: freecode-submit-$(VERS).tar.gz freecode-submit-$(VERS).md5 freecode-submit.html shipper version=$(VERS) | sh -e -x freecode-submit-2.7/control0000644000175000017500000000150712246652753014225 0ustar esresr# This is not a real Debian control file, but the syntax is upward-compatible. # It's project metadata for the shipper tool Package: freecode-submit Description: submit release information to freecode.com freecode-submit is a script that supports remote submission of release updates to Freecode via its JSON API. It is intended for use in project release scripts. It reads the metadata from an RFC-2822-like message on standard input, possibly with overrides by command-line switches. It supersedes freshmeat-submit, which no longer works following the site name change. XBS-Destinations: freecode Homepage: http://www.catb.org/~esr/freecode-submit XBS-HTML-Target: index.html Gitorious-URL: https://gitorious.org/freecode-submit XBS-Logo: gold-mega.png XBS-Freecode-Tags: freecode, json XBS-VC-Tag-Template: %(version)s freecode-submit-2.7/gold-mega.png0000644000175000017500000001156311473016351015154 0ustar esresrPNG  IHDR00WtEXtSoftwareAdobe ImageReadyqe<IDATxY \u=/}mF@HB1q1˦SHLp@%MLBe F$ B Hf5bff,=={^{gqJ+t՛=w9׌s燂ǧ> Z:E,E0LvH=0]X#5o˲`6f5l 6l⦵ 6_տF4 _e  p|*o;{ E\ażDVSg*W]̃1 >S`xc8' ίS3X :A [iO_2Z׃m}J~FWu/Xz`Fnv/Gwp3\Tيɶ8y2592$[_r%rh2A{ez~uWfp-_YhXU:vc~ vǑϟJB-!AG  lH/L+oGU)ȗ0mBO(p\6VP: l; uڇiDZ)?V?BA?#za2TUApn4OS 0GGh c_m5KLEڮc`0#DVtM" oAL_s#޵t۰7wu/Ši NW qߏFxLsbjJtxڛR ͋oUX97sFvvrRY^|^p) 9]Ϣ^-[?Y ÜLUH2J 4\4iLb-D*]-N .JD bi39gJlhwQ]=VP| Y>z;uA[NŊ++G=Y⁨n`luKRD8 \WDɅbXD7\,Oxnr|BQm(}\ N)F@Q Blsjq4̼ wL]>wLz^ c%0Q4y^SU>K <_\*y k{^l}qDjsdl7ԋBhX^l=gn"'߇/`ί`9&LJ0~|gBF' "6qj&P=2ɍX>DO.eSƵưŕBhMV+=%V2'Ɉ::`V*±G(ש!e-xi%_5rY.9E¤BX0*Ri%1ӥ uӆ3V3խ/F7W>(U|huBy0g`ɖ6<QExɨbqBQF-"Yu.*⵬\T`t]YZjCj5wX8x~[ jnuWWR\Ŧ6К? Xmx`&jHj"!DaD z!^x@<6US~xa;,xQԱkԒ1?QuuGk`Il?5RPAXMq䭇6 G5ԄhodHx] )ڪP>*zAs4; ;IPpٛ}YV Yإ[5kcyr `M]۴-{ 8<@E$ˏH%P}`$ݐG8{it98e *  A|~]c#Q^)֑ t+!sls/B.!XZH7k;Ȗmԏ~DnD{oL67^ã^JuR"C*F}2է,Q<|b1e,Z'lQMѠյ$zJbj_% 2k/FE"xlQǃ4>mQZF$Bdnϫ30]uE}GqB>DH2 GcljZc2')C)dwD: +`{b2IԌ8N8^ KBe'X(x٢cІqS{EQѩ%퇄NPMjU{g3(䲒E3h8(y6%GU&7cYu0N8bRnELU/4aDoutUl3O A_˃J 8y Q*Ui\>8TէV\2y^d⎬D#N_Zԃ$#"K~ 8&^.Y~QJʼ m[3TjVEƫtscߔSR__;EC$$u4G`0x]@U`9e~tbO?}]W.G|l" NÏo{N23mv.3IM˵,{lU*8ojiQJ"6զB (y.jB-$6Ba%37F[u9X؎{868MewνiQS.`tnBbeB̑_(4%5VJ=5'IiJ?!T$P:q fZvVF_GrVZJycF-I" sn8ClKUtՏ ߊz6Nӓ.gu" b,U׼7`Р.Jx]UZG^h,_ Ň;tX|%x'vwCY^Tx{ XɋD6SOvl7B]jQamۻhm՘8[<- PSSU?P(G|{#)s>i l7& "=K$'|Zn՘*Lk$h4[Œ/ n8wޠ5PTQD3W`e 2EJ)G "[U@?BL}C3?}6uێP<7)2!3HG>:;;=V0`-]pi1?X]ا0,݅P&kqm JuQV2߿Zh<s7h8|cH#_NMOsޓ}z].ޏn*z L_7bmKGZ`$PH|qc={'xo^Gh)&G ֽȑop+vto |,db S̔h[ $]7enud*0rC;5}-r ѬŠSNhQ)#LITD*DQMJQ81+S_/Lvwt[{5薏+'V4*b̎vɄN_\E TOW`Xg%Пu]=C'8'A#eYdsb1C[sEmD-!ѥQ|!\ӄe *ٺG"T,R0{>#BoIENDB`freecode-submit-2.7/freecode-submit.10000664000175000017500000002343412256273102015752 0ustar esresr'\" t .\" Title: freecode-submit .\" Author: [see the "AUTHORS" section] .\" Generator: DocBook XSL Stylesheets v1.78.1 .\" Date: 12/24/2013 .\" Manual: Development Tools .\" Source: freecode-submit .\" Language: English .\" .TH "FREECODE\-SUBMIT" "1" "12/24/2013" "freecode\-submit" "Development Tools" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" freecode-submit \- submit release announcements and project metadata updates to freecode\&.com .SH "SYNOPSIS" .HP \w'\fBfreecode\-submit\fR\ 'u \fBfreecode\-submit\fR [\-q] [\-V] [\-n] [\-N] [\-d] [\-\-showversion] [\fIdata\-options\fR] [\fIdata\-options\fR...] .SH "DESCRIPTION" .PP freecode\-submit is a command\-line tool for submitting release announcements to freecode\&.com\&. It is intended for batch\-mode operation in project release scripts, and designed so that its input format can easily be generated by scripts\&. .PP freecode\-submit accepts release information from a job card (an email\-message\-like data block on standard input) or from command\-line flags\&. Values set with command\-line flags override those collected from the job card\&. The accumulated data is entered into the freecode database via its API\&. .PP A few flags control the operation of freecode\-submit itself\&. .PP \-q, \-\-query .RS 4 Query the specified project\&. Delivers to standard output a job card describing the project metadata that can be edited and fed back to this tool\&. The data with release rather than project scope is for the most recent release\&. .RE .PP \-d, \-\-delete .RS 4 Delete the specified release rather than submitting it\&. With this option, all data other than Project and Release are ignored\&. Note: only works if the release has been submitted but not yet passed by a moderator; if the release is already posted, invoking this mode will throw an error\&. .RE .PP \-n, \-\-no\-stdin .RS 4 Process command\-line options only; don\*(Aqt read data from standard input\&. .RE .PP \-N, \-\-dryrun .RS 4 Generate JSON, but don\*(Aqt ship any modification requests to Freecode\&. Useful for debugging in combination with \-V\&. Note, this mode may generate requests which read data from Freecode in order to get permalink data\&. .RE .PP \-V, \-\-verbose .RS 4 Enable verbose debugging of the transaction\&. This option is mainly for developers\&. .RE .PP \-\-showversion .RS 4 Show the version of this program and exit\&. .RE .PP Release information is accepted from sources in the following order: .sp .RS 4 .ie n \{\ \h'-04' 1.\h'+01'\c .\} .el \{\ .sp -1 .IP " 1." 4.2 .\} An RFC\-2822\-format job card, strongly resembling an ordinary email message, on standard input\&. The message header fields each specify a particular item of release information; the body (if present) becomes the change announcement text\&. Within URL fields, the string ${version} will be replaced with the contents of the Version field\&. .RE .sp .RS 4 .ie n \{\ \h'-04' 2.\h'+01'\c .\} .el \{\ .sp -1 .IP " 2." 4.2 .\} Command\-line switches\&. .RE .PP Here is a table of metadata fields and their corresponding command\-line switches: .TS allbox tab(:); lB lB lB lB lB. T{ Message field T}:T{ Scope T}:T{ Short switch T}:T{ Long switch T}:T{ Explanation T} .T& l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l l. T{ Project: T}:T{ Project T}:T{ \-P T}:T{ \-\-project T}:T{ .PP Name of the project (freecode shortname) to operate on\&. You cannot change the project\-name attribute with this program; to do that, you need to use the Freecode web interface\&. T} T{ Summary: T}:T{ Project T}:T{ \-S T}:T{ \-\-summary T}:T{ .PP One\-line summary of the project\&. T} T{ Description: T}:T{ Project T}:T{ \-D T}:T{ \-\-description T}:T{ .PP Multiline description of the project\&. (Use RFC\-822\-style continuation lines) T} T{ License\-List: T}:T{ Project T}:T{ \-L T}:T{ \-\-license\-list T}:T{ .PP Specify the licenses under which the project is issued\&. This may be a comma\-separated list\&. T} T{ Project\-Tag\-List: T}:T{ Release T}:T{ \-T T}:T{ \-\-project\-tag\-list T}:T{ .PP Tags to attach to this project\&. May be a comma\-separated list\&. T} T{ Version: T}:T{ Release T}:T{ \-v T}:T{ \-\-version T}:T{ .PP Version string to be associated with the release\&. T} T{ Changes: T}:T{ Release T}:T{ \-c T}:T{ \-\-changes T}:T{ .PP The Changes field\&. If no Changes field or option is already present, the changes text is taken from the body of the RFC\-822 message on standard input\&. T} T{ Release\-Tag\-List: T}:T{ Release T}:T{ \-t T}:T{ \-\-tag\-list T}:T{ .PP Tags to attach to this release\&. May be a comma\-separated list\&. T} T{ Hide: T}:T{ Release T}:T{ \-x T}:T{ \-\-hide T}:T{ .PP If this field is present and has the value \(lqY\(rq, this release will not be visible on the project page\&. T} .TE .sp 1 .PP Additionally, you can specify tagged URL fields for the Freecode project record with header lines ending in "\-URL:"\&. The tag will be the header with the "\-URL:" suffix stripped off\&. Some examples of how to set frequently\-used URL types: .TS allbox tab(:); lB lB lB. T{ Message field T}:T{ Tag T}:T{ Usage T} .T& l l l l l l l l l l l l l l l. T{ Website\-URL: T}:T{ Website T}:T{ Project website home page\&. If you specify this, it will be used to activate the "More Information" link and Home icon on the project page\&. T} T{ Download\-URL: T}:T{ Download T}:T{ Preferred download URL\&. If you specify this, it will be used to activate the "Download" link and floppy\-disk icon on the project page\&. T} T{ Tar/GZ\-URL: T}:T{ Tar/GZ T}:T{ tar archive compressed with gzip T} T{ Tar/BZ\-URL: T}:T{ Tar/BZ T}:T{ tar archive compressed with bzip T} T{ Changelog\-URL T}:T{ Changelog T}:T{ project change log T} .TE .sp 1 .PP Note that the list of URLs you ship does not merely add to the existing list but overwrites it \- that is how you delete old URLs which are no longer valid\&. .PP The Summary, Description, License\-List, Project\-Tag\-List and all URL fields, when specified, actually change the record for the project\&. Only the Tag\-List, Changes, Version, and Hide fields are actually stored for each version\&. .PP The following elements of Freecode project metadata cannot yet be modified using this tool: \fIname\fR, \fItranslation list\fR, \fIprogramming language list\fR, \fIoperating system list\fR, \fIapproved screenshots\fR, and dependency records\&. .PP Support for updating all these elements except \fIname\fR is planned in future releases\&. .SH "USAGE" .PP Here is an example of a release\-information record that could be fed to freecode\-submit on standard input: .sp .if n \{\ .RS 4 .\} .nf Project: doclifter Version: 1\&.1 Hide: N Website\-URL: http://www\&.catb\&.org/~esr/doclifter/ Tar/GZ\-URL: http://www\&.catb\&.org/~esr/doclifter/doclifter\-${version}\&.tar\&.gz Fixed a bug in conditional evaluation that twadmin(8) tickled\&. Better detection of pure inclusions\&. Better blank\-section elimination\&. Kleene star recognized as \&.\&.\&. synonym in command synopses\&. Correct some bugs in semantic\-hint collection\&. Recognize Qt manual pages and use their conventions\&. Better lifting of mandoc\-generated pages\&. Translate groff\-style \e[\&.\&.\&.] escapes, flag unknown ones\&. Can now parse K&R style function prototypes as well as ANSI ones\&. This version lifts 96% of 9829 manual pages in a full Red Hat 9 installation with Fedora updates to *validated* XML\-DocBook\&. .fi .if n \{\ .RE .\} .SH "WARNING" .PP Since this program was first written, Freecode has changed its data API significantly (and its name, too; it used to be \*(AqFreshmeat\*(Aq)\&. While we have attempted to maintain backward compatibility, the data model has changed in significant ways\&. .PP There is no longer a Branch attribute\&. .PP The old Release\-Focus field is gone\&. .PP The old License field is now License\-List and can take a comma\-separated list of licenses\&. .PP All the old URL fields are gone\&. They\*(Aqre replaced by the general mechanism for pairing URLs with labels\&. .PP Earlier versions parsed RPM specfiles\&. This was poor separation of function and has been removed\&. That responsibility belongs to the human or program generating the job card\&. .SH "FILES" .PP ~/\&.netrc .RS 4 freecode\-submit expects to find your Freecode authorization tag here\&. The correct form for an entry looks like this: .sp .if n \{\ .RS 4 .\} .nf machine freecode account password none .fi .if n \{\ .RE .\} .sp For security, make sure your ~/\&.netrc file is not world\-readable; we recommend doing \fBchmod 600 ~/\&.netrc\fR\&. .RE .SH "BUGS" .PP The URLs returned in a project metadata query are Freecode redirectors, not the actual URLS supplied by previous project updates\&. This is due to a limitation in the Freecode API which may be fixed in future versions of that API\&. .SH "RETURN VALUES" .PP 0 on success, 1 on failure\&. In case of failure, any error message passed back by the Freecode API is issued to standard error\&. .SH "AUTHORS" .PP Eric S\&. Raymond \&.