# HG changeset patch # User Shabe Razvi # Date 1265214284 0 # Node ID 44e403e0f4cde50860d45bc4dd13537b977c22ba # Parent 1daa251167e8ebff7f0fb0a59797ce1d4ae91d42# Parent e4ad889f1aa5d21af148586cd3295bf9cfe8fefc Merge diff -r e4ad889f1aa5 -r 44e403e0f4cd .hgtags --- a/.hgtags Thu Jan 07 11:16:14 2010 +0000 +++ b/.hgtags Wed Feb 03 16:24:44 2010 +0000 @@ -5,3 +5,4 @@ 718b119bed63ae5b12b9beda8e02576232eaa131 PDK_2.0.1 61b66a9de9154bf58b1fc75210d07bc5c5c1c678 PDK_2.0.2 c5817fd289eca8bf8f86c29d77c175c6392d440a PDK_3.0.d +c63eca238256f2129b2416f7023930bb18ca5fec PDK_3.0.e diff -r e4ad889f1aa5 -r 44e403e0f4cd clone_packages/sf_fcl_packages.txt --- a/clone_packages/sf_fcl_packages.txt Thu Jan 07 11:16:14 2010 +0000 +++ b/clone_packages/sf_fcl_packages.txt Wed Feb 03 16:24:44 2010 +0000 @@ -1,4 +1,4 @@ -https://developer.symbian.org/sfl/FCL/sf/adaptation/stubs +https://developer.symbian.org/oss/FCL/sf/adaptation/stubs https://developer.symbian.org/sfl/FCL/sf/app/camera https://developer.symbian.org/sfl/FCL/sf/app/commonemail https://developer.symbian.org/sfl/FCL/sf/app/conntools @@ -116,6 +116,7 @@ https://developer.symbian.org/sfl/FCL/sf/tools/rndtools https://developer.symbian.org/sfl/FCL/sf/tools/swconfigtools https://developer.symbian.org/oss/FCL/sf/app/webuis +https://developer.symbian.org/oss/FCL/sf/mw/gstreamer https://developer.symbian.org/oss/FCL/sf/mw/serviceapi https://developer.symbian.org/oss/FCL/sf/mw/serviceapifw https://developer.symbian.org/oss/FCL/sf/mw/web @@ -128,5 +129,6 @@ https://developer.symbian.org/oss/FCL/interim/fbf/configs/pkgbuild https://developer.symbian.org/oss/FCL/interim/fbf/projects/packages https://developer.symbian.org/oss/FCL/interim/fbf/projects/platforms +http://developer.symbian.org/oss/FCL/interim/sf-test/platform/smoketest https://developer.symbian.org/oss/FCL/sf/adaptation/beagleboard diff -r e4ad889f1aa5 -r 44e403e0f4cd clone_packages/sf_mcl_packages.txt --- a/clone_packages/sf_mcl_packages.txt Thu Jan 07 11:16:14 2010 +0000 +++ b/clone_packages/sf_mcl_packages.txt Wed Feb 03 16:24:44 2010 +0000 @@ -1,4 +1,4 @@ -https://developer.symbian.org/sfl/MCL/sf/adaptation/stubs +https://developer.symbian.org/oss/MCL/sf/adaptation/stubs https://developer.symbian.org/sfl/MCL/sf/app/camera https://developer.symbian.org/sfl/MCL/sf/app/commonemail https://developer.symbian.org/sfl/MCL/sf/app/conntools @@ -115,6 +115,8 @@ https://developer.symbian.org/sfl/MCL/sf/tools/swconfigtools https://developer.symbian.org/oss/MCL/sf/adaptation/qemu https://developer.symbian.org/oss/MCL/sf/app/webuis +https://developer.symbian.org/oss/MCL/sf/mw/gstreamer +https://developer.symbian.org/oss/MCL/sf/mw/qt https://developer.symbian.org/oss/MCL/sf/mw/serviceapi https://developer.symbian.org/oss/MCL/sf/mw/serviceapifw https://developer.symbian.org/oss/MCL/sf/mw/web diff -r e4ad889f1aa5 -r 44e403e0f4cd clone_packages/sftools_fcl_packages.txt --- a/clone_packages/sftools_fcl_packages.txt Thu Jan 07 11:16:14 2010 +0000 +++ b/clone_packages/sftools_fcl_packages.txt Wed Feb 03 16:24:44 2010 +0000 @@ -22,6 +22,7 @@ https://developer.symbian.org/sfl/FCL/sftools/dev/ui https://developer.symbian.org/oss/FCL/sftools/dev/eclipseenv/buildlayout34 https://developer.symbian.org/oss/FCL/sftools/dev/eclipseenv/eclipse +https://developer.symbian.org/oss/FCL/sftools/dev/eclipseenv/wrttools/ https://developer.symbian.org/oss/FCL/sftools/dev/hostenv/compilationtoolchains https://developer.symbian.org/oss/FCL/sftools/dev/hostenv/cpptoolsplat https://developer.symbian.org/oss/FCL/sftools/dev/hostenv/dist diff -r e4ad889f1aa5 -r 44e403e0f4cd clone_packages/sftools_mcl_packages.txt --- a/clone_packages/sftools_mcl_packages.txt Thu Jan 07 11:16:14 2010 +0000 +++ b/clone_packages/sftools_mcl_packages.txt Wed Feb 03 16:24:44 2010 +0000 @@ -14,14 +14,17 @@ https://developer.symbian.org/sfl/MCL/sftools/depl/swconfigapps/swmgnttoolsguides https://developer.symbian.org/sfl/MCL/sftools/depl/swconfigapps/sysmodeltools https://developer.symbian.org/sfl/MCL/sftools/depl/swconfigmdw -https://developer.symbian.org/oss/MCL/sftools/dev/build https://developer.symbian.org/sfl/MCL/sftools/dev/dbgsrvsmdw https://developer.symbian.org/sfl/MCL/sftools/dev/devicedbgsrvs -https://developer.symbian.org/sfl/MCL/sftools/dev/ide/carbidecppplugins https://developer.symbian.org/sfl/MCL/sftools/dev/iss https://developer.symbian.org/sfl/MCL/sftools/dev/ui +https://developer.symbian.org/oss/MCL/sftools/depl/docscontent +https://developer.symbian.org/oss/MCL/sftools/depl/doctools +https://developer.symbian.org/oss/MCL/sftools/dev/build https://developer.symbian.org/oss/MCL/sftools/dev/eclipseenv/buildlayout34 +https://developer.symbian.org/oss/MCL/sftools/dev/eclipseenv/buildlayout35 https://developer.symbian.org/oss/MCL/sftools/dev/eclipseenv/eclipse +https://developer.symbian.org/oss/MCL/sftools/dev/eclipseenv/wrttools https://developer.symbian.org/oss/MCL/sftools/dev/hostenv/compilationtoolchains https://developer.symbian.org/oss/MCL/sftools/dev/hostenv/cpptoolsplat https://developer.symbian.org/oss/MCL/sftools/dev/hostenv/dist @@ -29,3 +32,4 @@ https://developer.symbian.org/oss/MCL/sftools/dev/hostenv/makeng https://developer.symbian.org/oss/MCL/sftools/dev/hostenv/pythontoolsplat https://developer.symbian.org/oss/MCL/sftools/dev/ide/carbidecpp +https://developer.symbian.org/oss/MCL/sftools/dev/ide/carbidecppplugins diff -r e4ad889f1aa5 -r 44e403e0f4cd downloadkit/downloadkit.py --- a/downloadkit/downloadkit.py Thu Jan 07 11:16:14 2010 +0000 +++ b/downloadkit/downloadkit.py Wed Feb 03 16:24:44 2010 +0000 @@ -19,11 +19,15 @@ import sys import getpass import re +import time from BeautifulSoup import BeautifulSoup +from optparse import OptionParser user_agent = 'downloadkit.py script' headers = { 'User-Agent' : user_agent } top_level_url = "http://developer.symbian.org" +download_list = [] +unzip_list = [] username = '' password = '' @@ -112,8 +116,123 @@ def run(self): self.status = self.unzip(self.filename, self.levels, self.deletelevels) -def downloadkit(version): - headers = { 'User-Agent' : user_agent } +threadlist = [] +def schedule_unzip(filename, unziplevel, deletelevel): + global options + if options.nounzip : + return + if options.dryrun : + global unzip_list + if unziplevel > 0: + unzip_list.append("7z x -y %s" % filename) + if unziplevel > 1: + unzip_list.append("# unzip recursively %d more times" % unziplevel-1) + if deletelevel > 0: + unzip_list.append("# delete %s" % filename) + if deletelevel > 1: + unzip_list.append("# delete zip files recursively %d more times" % deletelevel-1) + return + + unzipthread = unzipfile(filename, unziplevel, deletelevel) + global threadlist + threadlist.append(unzipthread) + unzipthread.start() + +def complete_outstanding_unzips(): + global options + if options.dryrun or options.nounzip: + return + print "Waiting for outstanding commands to finish..." + for thread in threadlist: + thread.join() + +def orderResults(x,y) : + def ranking(name) : + # 1st = release_metadata, build_BOM.zip (both small things!) + if re.match(r"(build_BOM|release_metadata)", name): + return 1000; + # 2nd = tools, binaries (required for execution and compilation) + elif re.match(r"(binaries_|tools_)", name): + return 2000; + # 3rd = rnd binaries, binary patches + elif re.match(r"(bin_)", name): + return 3000; + # 4th = sources + elif re.match(r"(src_sfl|src_oss)", name): + return 4000; + # 5rd = rnd sources, source patches (not sure we'd ever have those) + elif re.match(r"(src_)", name): + return 5000; + # Last, anything else + return 10000; + xtitle = x['title'] + ytitle = y['title'] + return cmp(ranking(xtitle)+cmp(xtitle,ytitle), ranking(ytitle)) + +def download_file(filename,url): + global options + if options.dryrun : + global download_list + download_info = "download %s %s" % (filename, url) + download_list.append(download_info) + return True + + print 'Downloading ' + filename + global headers + req = urllib2.Request(url, None, headers) + + try: + response = urllib2.urlopen(req) + CHUNK = 128 * 1024 + size = 0 + filesize = -1 + last_time = time.time() + last_size = size + fp = open(filename, 'wb') + while True: + chunk = response.read(CHUNK) + if not chunk: break + if size == 0 and chunk.find('
') != -1: + # our urllib2 cookies have gone awol - login again + login(False) + req = urllib2.Request(url, None, headers) + response = urllib2.urlopen(req) + chunk = response.read(CHUNK) + if size == 0: + filesize = int(response.info()['Content-Length']) + fp.write(chunk) + size += len(chunk) + now = time.time() + if options.progress and now-last_time > 20: + rate = (size-last_size)/(now-last_time) + estimate = "" + if filesize > 0 and rate > 0: + remaining_seconds = (filesize-size)/rate + if remaining_seconds > 110: + remaining = "%d minutes" % (remaining_seconds/60) + else: + remaining = "%d seconds" % remaining_seconds + estimate = "- %d%% est. %s" % ((100*size/filesize), remaining) + print "- %d Kb (%d Kb/s) %s" % (size/1024, (rate/1024)+0.5, estimate) + last_time = now + last_size = size + fp.close() + if options.progress: + now = time.time() + print "- Completed %s - %d Kb in %d seconds" % (filename, (filesize/1024)+0.5, now-last_time) + + #handle errors + except urllib2.HTTPError, e: + print "HTTP Error:",e.code , downloadurl + return False + except urllib2.URLError, e: + print "URL Error:",e.reason , downloadurl + return False + return True + +def downloadkit(version): + global headers + global options urlbase = 'http://developer.symbian.org/main/tools_and_kits/downloads/' viewid = 5 # default to Symbian^3 @@ -140,57 +259,55 @@ soup=BeautifulSoup(doc) results=soup.findAll('a', href=re.compile("^download"), title=re.compile("\.(zip|xml)$")) + results.sort(orderResults) for result in results: downloadurl = urlbase + result['href'] filename = result['title'] - print 'Downloading ' + filename - req = urllib2.Request(downloadurl, None, headers) - - try: - response = urllib2.urlopen(req) - CHUNK = 128 * 1024 - first_chunk = True - fp = open(filename, 'wb') - while True: - chunk = response.read(CHUNK) - if not chunk: break - if first_chunk and chunk.find('
') != -1: - # our urllib2 cookies have gone awol - login again - login(False) - req = urllib2.Request(downloadurl, None, headers) - response = urllib2.urlopen(req) - chunk = response.read(CHUNK) - fp.write(chunk) - first_chunk = False - fp.close() - #handle errors - except urllib2.HTTPError, e: - print "HTTP Error:",e.code , downloadurl - except urllib2.URLError, e: - print "URL Error:",e.reason , downloadurl + if options.nosrc and re.match(r"(src_sfl|src_oss)", filename) : + continue # no snapshots of Mercurial source thanks... + + if download_file(filename, downloadurl) != True : + continue # download failed # unzip the file (if desired) + if re.match(r"patch", filename): + complete_outstanding_unzips() # ensure that the thing we are patching is completed first + if re.match(r"(bin|tools).*\.zip", filename): - unzipthread = unzipfile(filename, 1, 0) # unzip once, don't delete - threadlist.append(unzipthread) - unzipthread.start() + schedule_unzip(filename, 1, 0) # unzip once, don't delete elif re.match(r"src_.*\.zip", filename): - unzipthread = unzipfile(filename, 1, 1) # zip of zips, delete top level - threadlist.append(unzipthread) - unzipthread.start() + schedule_unzip(filename, 1, 1) # zip of zips, delete top level elif re.match(r"build_BOM.zip", filename): - unzipthread = unzipfile(filename, 1, 1) # unpack then delete zip as it's not needed again - threadlist.append(unzipthread) - unzipthread.start() + schedule_unzip(filename, 1, 1) # unpack then delete zip as it's not needed again # wait for the unzipping threads to complete - print "Waiting for unzipping to finish..." - for thread in threadlist: - thread.join() + complete_outstanding_unzips() return 1 +parser = OptionParser(version="%prog 0.5.1", usage="Usage: %prog [options] version") +parser.add_option("-n", "--dryrun", action="store_true", dest="dryrun", + help="print the files to be downloaded, the 7z commands, and the recommended deletions") +parser.add_option("--nosrc", action="store_true", dest="nosrc", + help="Don't download any of the source code available directly from Mercurial") +parser.add_option("--nounzip", action="store_true", dest="nounzip", + help="Just download, don't unzip or delete any files") +parser.add_option("--progress", action="store_true", dest="progress", + help="Report download progress") +parser.set_defaults(dryrun=False, nosrc=False, nounzip=False, progress=False) + +(options, args) = parser.parse_args() +if len(args) != 1: + parser.error("Must supply a PDK version, e.g. 3.0.e") login(True) -downloadkit(sys.argv[1]) +downloadkit(args[0]) + +if options.dryrun: + print "# instructions for downloading kit " + args[0] + for download in download_list: + print download + for command in unzip_list: + print command + diff -r e4ad889f1aa5 -r 44e403e0f4cd hg_hooks/blacklist/COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hg_hooks/blacklist/COPYING Wed Feb 03 16:24:44 2010 +0000 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff -r e4ad889f1aa5 -r 44e403e0f4cd hg_hooks/blacklist/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hg_hooks/blacklist/README Wed Feb 03 16:24:44 2010 +0000 @@ -0,0 +1,34 @@ +hg blacklist + +manage repository changeset blacklist + + This extension is used to manage a blacklist for the repository. + Can blacklist changesets by changeset id, and regular expressions against + the user field of a changeset and also a changesets file list. + + Current rules can be viewed using the [-l|--list] operation. + + Each modification to a blacklist is logged. These can be viewed using the + --auditlog operation. + + Each time a changeset is blocked/denied it's logged. These can be viewed + using the --blocklog operation. + + Types of changeset blacklist rules can be defined implicitly or explicitly: + + If a rule definition contains between 12 and 40 hexadecimal characters + it is assumed to be a rule matched against changeset id. Can be set + explicitly set with the -n flag to the --add operation. + + If a rule definition contains a '@' it is assumed to be a rule matched + against a changeset's user property. Can be set explicitly with + the -u flag to the --add operation. + + Otherwise the rule is assumed to be matched against a changeset's file + list. Can be set explicitly with the -f flag to the --add operation. + + When this extension is enabled a hook is also added to the + 'pretxnchangegroup' action that will block any incoming changesets + (via pull/push/unbundle) if they are blacklisted. + It won't block any local commits. + diff -r e4ad889f1aa5 -r 44e403e0f4cd hg_hooks/blacklist/blacklist.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hg_hooks/blacklist/blacklist.py Wed Feb 03 16:24:44 2010 +0000 @@ -0,0 +1,542 @@ +#!/usr/bin/env python +# +# Copyright (C) 2010 Mozilla Foundation +# Copyright (C) 2010 Symbian Foundation +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +# Initial Contributors: +# Pat Downey +# +# Contributors: +# Your name here? +# +# Description: +# +# An extension to mercurial that adds the ability to specify a blacklist for +# a repository. That is to deny a changeset from being pushed/pulled/unbundled +# if it matches one of a set of patterns. +# +# At present it can deny nodes based on their changeset id, a regular expression +# matched against the user field, or a regular expression matched against the +# changeset's file list. +# +# Note: With the regular expression rules, if you want to match a string anywhere +# with in a string, e.g. create a rule against files within directories called +# 'internal' the rule would need to be ..*/internal/.*'. That is you need to be +# explicit in specifying a set of any characters otherwise it will perform a +# direct string comparison. # +# +# Requires sqlite extension (included in python 2.5 onwards) +# * Available for python 2.4 in python-sqlite2 package on RHEL5.2+ +# +# Ideas for implementation came strongly from: +# http://hg.mozilla.org/users/bsmedberg_mozilla.com/hghooks/file/tip/mozhghooks/pushlog.py +# +# + +'''manage repository changeset blacklist + +''' + +from mercurial import demandimport + +demandimport.disable() +try: + import sqlite3 as sqlite +except ImportError: + from pysqlite2 import dbapi2 as sqlite +demandimport.enable() + +import binascii +import os +import os.path +import re +import stat +import sys +import time +from datetime import datetime + + +# changeset identifier 12-40 hex chars +NODE_RE='^[0-9|a-f]{12,40}' + + + + +def blacklist(ui,repo,*args,**opts): + '''manage repository changeset blacklist + + This extension is used to manage a blacklist for the repository. + Can blacklist changesets by changeset id, and regular expressions against + the user field of a changeset and also a changesets file list. + + Current rules can be viewed using the [-l|--list] operation. + + Each modification to a blacklist is logged. These can be viewed using the + --auditlog operation. + + Each time a changeset is blocked/denied it's logged. These can be viewed + using the --blocklog operation. + + Types of changeset blacklist rules can be defined implicitly or explicitly: + + If a rule definition contains between 12 and 40 hexadecimal characters + it is assumed to be a rule matched against changeset id. Can be set + explicitly set with the -n flag to the --add operation. + + If a rule definition contains a '@' it is assumed to be a rule matched + against a changeset's user property. Can be set explicitly with + the -u flag to the --add operation. + + Otherwise the rule is assumed to be matched against a changeset's file + list. Can be set explicitly with the -f flag to the --add operation. + + When this extension is enabled a hook is also added to the + 'pretxnchangegroup' action that will block any incoming changesets + (via pull/push/unbundle) if they are blacklisted. + It won't block any local commits. + ''' + conn = openconn(ui, repo ) + if 'list' in opts and opts['list'] : + listblacklistrule(ui,conn,args,opts) + elif 'blocklog' in opts and opts['blocklog'] : + listblacklistblocklog(ui,conn,args,opts) + elif 'auditlog' in opts and opts['auditlog'] : + listblacklistauditlog(ui,conn,args,opts) + elif 'enable' in opts and opts['enable'] : + enableblacklistrule(ui,conn,args,opts) + elif 'disable' in opts and opts['disable'] : + disableblacklistrule(ui,conn,args,opts) + elif 'remove' in opts and opts['remove'] : + removeblacklistrule(ui,conn,args,opts) + elif 'add' in opts and opts['add'] : + addblacklistrule(ui,conn,args,opts) + else : + ui.warn( 'invalid operation specified\n' ) + + conn.close( ) + +####### Database setup methods +# this part derived from mozilla's pushlog.py hook +def openconn(ui,repo): + blacklistdb = os.path.join(repo.path, 'blacklist.db') + createdb = False + if not os.path.exists(blacklistdb): + createdb = True + conn = sqlite.connect(blacklistdb) + if not createdb and not schemaexists(conn): + createdb = True + if createdb: + createblacklistdb(ui,conn) + st = os.stat(blacklistdb) + os.chmod(blacklistdb, st.st_mode | stat.S_IWGRP) + + return conn + +# Derived from mozilla's pushlog hook +def schemaexists(conn): + return 3 == conn.execute("SELECT COUNT(*) FROM SQLITE_MASTER WHERE name IN ( ?, ?, ?)" , ['blacklist_rule','blacklist_auditlog','blacklist_blocklog']).fetchone()[0] + +# Derived from mozilla's pushlog hook +def createblacklistdb(ui,conn): + # record of different blacklist rule, type should be either 'node' or 'file' or 'user' + # 'node' - compare pattern with changeset identifier + # 'file' - used as regular expression against changeset file manifest + # 'user' - used as regular expression against changeset author/user + # (id,pattern,type,enabled) + conn.execute("CREATE TABLE IF NOT EXISTS blacklist_rule (id INTEGER PRIMARY KEY AUTOINCREMENT, pattern TEXT, type TEXT, enabled INTEGER,comment TEXT)") + conn.execute("CREATE UNIQUE INDEX IF NOT EXISTS blacklist_rule_idx ON blacklist_rule (pattern,type)" ) + + # records additions and modifications to the blacklist_rule table + # (id, operation, rule_id, user, date, comment) + conn.execute("CREATE TABLE IF NOT EXISTS blacklist_auditlog (id INTEGER PRIMARY KEY AUTOINCREMENT, operation TEXT, rule_id INTEGER, user TEXT, date INTEGER, comment TEXT)") + conn.execute("CREATE INDEX IF NOT EXISTS blacklist_auditlog_rule_idx ON blacklist_auditlog (rule_id)" ) + + # log attempted pushes and the http users trying to push a blocked changeset + # (id,rule_id,cset_id, cset_user, cset_desc, user,date) + conn.execute("CREATE TABLE IF NOT EXISTS blacklist_blocklog (id INTEGER PRIMARY KEY AUTOINCREMENT, rule_id INTEGER, cset_id TEXT, cset_user TEXT, cset_desc TEXT, user TEXT, date INTEGER)") + conn.execute("CREATE INDEX IF NOT EXISTS blacklist_blocklog_rule_idx ON blacklist_blocklog (rule_id)" ) + + conn.commit() + + +# Methods for extension commands +def __getblacklistruletype( ui, pattern, opts ): + type=None + + if opts['nodeType'] : + type = 'node' + elif opts['fileType'] : + type = 'file' + elif opts['userType'] : + type = 'user' + + # try and work out type of blacklist if none specified + # default to regexp + if type == None : + if re.match( NODE_RE, pattern ) : + type = 'node' + elif '@' in pattern : + type = 'user' + else : + type = 'file' + ui.note( 'type implicitly set to \'%s\'\n' % type ) + + return type + +def addblacklistrule(ui,conn,args,opts): + ret = 1 + if len(args) == 1 : + createrule = True + pattern = args[0] + + type = __getblacklistruletype( ui, pattern, opts ) + + if type == 'node' : + # if pattern has been specified as a node type + # check that pattern is a valid node + if not re.match( NODE_RE, pattern ) : + ui.warn( 'node should be 12 or 40 characters.\n' ) + createrule = False + + if createrule : + comment = None + + if 'desc' in opts and opts['desc'] : + if opts['desc'] != '' : + comment = opts['desc'] + + insertblacklistrule(ui,conn,pattern,type, comment=comment) + else : + ui.warn( 'missing pattern argument.\n' ) + + return ret + +def removeblacklistrule(ui,conn,args,opts): + if len(args) == 1 : + deleteblacklistrule(ui,conn,args[0]) + else : + ui.warn( 'rule id argument required.\n' ) + + return 0 + +def disableblacklistrule(ui,conn,args,opts): + if len(args) == 1 : + updateblacklistrule(ui,conn,args[0],False) + else : + ui.warn( 'rule id argument required.\n' ) + + return 0 + +def enableblacklistrule(ui,conn,args,opts): + if len(args) == 1 : + updateblacklistrule(ui,conn,args[0],True) + else : + ui.warn( 'rule id argument required.\n' ) + + return 0 + +def listblacklistrule(ui,conn,args,opts): + if len(args) in (0,1) : + res = selectblacklistrule(ui,conn,args) + + printblacklist(ui,res) + else : + ui.warn( 'too many arguments.\n' ) + + return 0 + +def listblacklistauditlog(ui,conn,args,opts): + if len(args) in (0,1) : + res = selectblacklistauditlog(ui, conn, args ) + + printauditlog(ui,res) + else : + ui.warn( 'too many arguments.\n' ) + + return 0 + +def listblacklistblocklog(ui,conn,args,opts): + if len(args) in (0,1) : + res = selectblacklistblocklog(ui, conn, args ) + + printblocklog(ui,res) + else : + ui.warn( 'too many arguments.\n' ) + + return 0 + +def insertblacklistaudit(ui, conn, operation, rule_id, comment=None ): + user = __getenvuser( ) + audit_date = int(time.time()) + + audit_sql = 'INSERT INTO blacklist_auditlog ( operation, rule_id, user, date, comment ) VALUES ( ?, ?, ?, ?, ? )' + conn.execute( audit_sql, (operation, rule_id, user, audit_date, comment ) ) + +def insertblacklistrule(ui, conn, pattern, type, enabled=True, comment=None): + rule_sql = 'INSERT INTO blacklist_rule ( pattern, type, enabled,comment ) VALUES ( ?, ?, ?, ? )' + + res = conn.execute( rule_sql, (pattern,type,enabled,comment) ) + rule_id= res.lastrowid + + insertblacklistaudit(ui, conn, 'add', rule_id,comment=comment ) + + conn.commit( ) + +def __getenvuser( ): + # look at REMOTE_USER first + # then look at LOGUSER + # then look at USER + for e in ['REMOTE_USER','SUDO_USER','LOGUSER','USER'] : + if e in os.environ : + user = '%s:%s' %( e, os.environ.get( e ) ) + break + + return user + +def insertblacklistblocklog( ui, conn, rule, ctx ): + # (id, rule_id, user, date) + rule_id=rule[0] + + log_user = __getenvuser( ) + audit_date = int(time.time()) + + ctx_node = binascii.hexlify(ctx.node()) + ctx_user = ctx.user() + ctx_desc = ctx.description() + + log_sql = 'INSERT INTO blacklist_blocklog (rule_id,user,date,cset_id,cset_user,cset_desc) VALUES (?,?,?,?,?,?)' + conn.execute( log_sql, (rule_id,log_user,audit_date, ctx_node, ctx_user, ctx_desc)) + conn.commit() + +def updateblacklistrule(ui, conn, rule_id, enabled): + rule_sql = 'UPDATE blacklist_rule SET enabled=? WHERE id=?' + + conn.execute( rule_sql, [enabled, rule_id] ) + + insertblacklistaudit(ui, conn, 'update', rule_id, 'enabled=%s' % enabled ) + + conn.commit( ) + +def deleteblacklistrule(ui, conn, rule_id ): + if rule_id != None : + res = selectblacklistrule(ui, conn, rule_id ) + processed = False + for (id,pattern,type,enabled,comment) in res : + comment = 'deleted: pattern=%s, type=%s, enabled=%s' % (pattern, type, enabled) + + rule_sql = 'DELETE FROM blacklist_rule WHERE id=?' + conn.execute( rule_sql, [rule_id] ) + + insertblacklistaudit(ui, conn, 'delete', rule_id, comment) + + conn.commit( ) + processed = True + + if not processed : + ui.warn( 'no matching blacklist rule found with id %s\n' % rule_id ) + else : + ui.warn( 'no rule id specified\n' ) + +def selectblacklistrule(ui, conn, rule_id ): + # (id, operation, rule_id, user, date, comment) + if rule_id : + rule_sql = 'SELECT id,pattern,type,enabled,comment FROM blacklist_rule WHERE id=? ORDER BY id ASC' + res = conn.execute( rule_sql, rule_id ) + else : + rule_sql = 'SELECT id,pattern,type,enabled,comment FROM blacklist_rule ORDER BY id ASC' + res = conn.execute( rule_sql ) + + return res + +def selectblacklistauditlog(ui,conn,rule_id=None) : + # (id, operation, rule_id, user, date, comment) + if rule_id : + rule_sql = 'SELECT id,operation,rule_id,user,date,comment FROM blacklist_auditlog WHERE rule_id=? ORDER BY date ASC' + res = conn.execute( rule_sql, rule_id ) + else : + rule_sql = 'SELECT id,operation,rule_id,user,date,comment FROM blacklist_auditlog ORDER BY date ASC' + res = conn.execute( rule_sql ) + + return res + +def selectblacklistblocklog(ui,conn,rule_id=None) : + # (id, rule_id, node, user, date) + if rule_id : + rule_sql = 'SELECT id,rule_id,cset_id,cset_user,cset_desc,user,date FROM blacklist_blocklog WHERE rule_id=? ORDER BY date ASC' + res = conn.execute( rule_sql, rule_id ) + else : + rule_sql = 'SELECT id,rule_id,cset_id,cset_user,cset_desc,user,date FROM blacklist_blocklog ORDER BY date ASC' + res = conn.execute( rule_sql ) + + return res + +def printblacklist(ui,res): + for r in res : + (id,pattern,type,enabled,comment) = r + + if enabled == 1 : + enabled = True + elif enabled == 0 : + enabled = False + + ui.write( 'rule: %d:%s\n' % (id,type) ) + ui.write( 'pattern: %s\n' % pattern ) + ui.write( 'enabled: %s\n' % enabled ) + if comment : + ui.write( 'comment: %s\n' % comment ) + ui.write( '\n' ) + +def printauditlog(ui,res): + for r in res : + (id, operation, rule_id, user, date, comment) = r + + date = datetime.utcfromtimestamp(date).isoformat() + + if not comment : + comment = '' + + ui.write( 'date: %s\n' % date ) + ui.write( 'operation: %s\n' % operation ) + ui.write( 'user: %s\n' % user ) + ui.write( 'rule: %s\n' % rule_id ) + ui.write( 'comment: %s\n' % comment ) + ui.write( '\n' ) + +def printblocklog(ui,res): + for r in res : + (id, rule_id, cset_id, cset_user, cset_desc, user, date) = r + + date = datetime.utcfromtimestamp(date).isoformat() + + ui.write( 'cset: %s\n' % cset_id ) + ui.write( 'cset-user: %s\n' % cset_user) + ui.write( 'cset-desc: %s\n' % cset_desc ) + ui.write( 'rule: %s\n' % rule_id ) + ui.write( 'date: %s\n' % date ) + ui.write( 'user: %s\n' % user ) + + ui.write( '\n' ) + + +# Hook specific functions follow + +def excludecsetbyfile(ctx,pattern): + exclude = False + + file_re = re.compile( '%s' % pattern, re.I ) + for f in ctx.files() : + if file_re.match( f ) : + exclude = True + break + + return exclude + +def excludecsetbynode(ctx,pattern): + exclude = False + + node = binascii.hexlify(ctx.node()) + + if node.startswith( pattern ) : + exclude = True + + return exclude + +def excludecsetbyuser(ctx,pattern): + exclude = False + userStr = ctx.user() + + user_re = re.compile( '^.*%s.*$' % pattern, re.I ) + if user_re.match( userStr ) : + exclude = True + + return exclude + +def excludeblacklistcset(ui,conn,ctx): + + bl_sql = 'SELECT id,pattern,type FROM blacklist_rule WHERE enabled=1' + res = conn.execute( bl_sql ) + + (exclude,rule) = (False,None) + + for (id,pattern,type) in res : + if type == 'node' : + exclude = excludecsetbynode(ctx,pattern) + elif type == 'user' : + exclude = excludecsetbyuser(ctx,pattern) + elif type == 'file' : + exclude = excludecsetbyfile(ctx,pattern) + else : + ui.warn('unrecognised rule type \'%s\'' % type ) + + if exclude : + rule = (id,pattern,type) + break + + return (exclude,rule) + +# The hook method that is used to block bad changesets from being introduced +# to the current repository +def pretxnchangegroup(ui,repo,hooktype,node,**args): + start = repo[node].rev() + end = len(repo) + + conn = openconn(ui, repo ) + + blocked = False + + for rev in xrange(start, end): + ctx = repo[rev] + (blocked,rule) = excludeblacklistcset( ui, conn, ctx) + + if blocked : + insertblacklistblocklog( ui, conn, rule, ctx ) + (id,pattern,type) = rule + ui.write( 'blocked: cset %s in changegroup blocked by blacklist\n' % str(ctx) ) + ui.write( 'blocked-reason: %s matched against \'%s\'\n' % ( type,pattern )) + break + + conn.close( ) + + return blocked + +def setupblacklisthook(ui): + ui.setconfig('hooks', 'pretxnchangegroup.blacklist', pretxnchangegroup) + +def reposetup(ui,repo): + # print 'in blacklist reposetup' + setupblacklisthook( ui ) + +def uisetup(ui): + # print 'in blacklist uisetup' + setupblacklisthook( ui ) + +cmdtable = { + 'blacklist': (blacklist, + [ + ('l','list',None,'list blacklist entries'), + ('','blocklog',None,'list blocked changesets'), + ('','auditlog',None,'show audit log for blacklist'), + ('a','add',None,'add node to blacklist'), + ('d','disable',None,'disable blacklist rule'), + ('e','enable',None,'enable blacklist rule'), + ('r','remove',None,'remove node from blacklist'), + ('n','nodeType',False,'parse argument as node to blacklist'), + ('f','fileType',False,'parse argument as file path to blacklist'), + ('u','userType',False,'parse argument as user regexp to blacklist'), + ('','desc','','comment to attach to rule')], + "") + } diff -r e4ad889f1aa5 -r 44e403e0f4cd williamr/convert_to_eula.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/williamr/convert_to_eula.py Wed Feb 03 16:24:44 2010 +0000 @@ -0,0 +1,142 @@ +#!/usr/bin/python +# Copyright (c) 2009 Symbian Foundation. +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Symbian Foundation - Initial contribution +# +# Description: +# Map the SFL license to the EULA license, keeping a copy of the original file +# in a parallel tree for creation of a "repair" kit to reinstate the SFL + +import os +import os.path +import re +import codecs + +oldtext0 = re.compile('terms of the License "Symbian Foundation License v1.0"(to Symbian Foundation)?') +oldtext1 = re.compile('the URL "http:..www.symbianfoundation.org/legal/sfl-v10.html"') + +newtext = [ + 'terms of the License "Symbian Foundation License v1.0" to Symbian Foundation members and "Symbian Foundation End User License Agreement v1.0" to non-members', + 'the URL "http://www.symbianfoundation.org/legal/licencesv10.html"' +] + +errorfiles = [] +multinoticefiles = [] +shadowroot = 'shadow_epoc32' + +def file_type(file) : + f = open(file, 'r') + data = f.read(256) + f.close() + if len(data) < 2: + return None # too short to be worth bothering about anyway + if data[0] == chr(255) and data[1] == chr(254) : + return 'utf_16_le' + if data.find(chr(0)) >= 0 : + return None # zero byte implies binary file + return 'text' + +def map_eula(dir, name, encoded) : + global oldtext0 + global newtext1 + global newtext + file = os.path.join(dir, name) + if encoded == 'text': + f = open(file, 'r') + else: + f = codecs.open(file, 'r', encoding=encoded) + lines = f.readlines() + # print ">> %s encoded as %s" % (file, f.encoding) + f.close() + + updated = 0 + newlines = [] + while len(lines) > 0: + line = lines.pop(0) + pos1 = oldtext0.search(line) + if pos1 != None: + # be careful - oldtext is a prefix of newtext + if pos1.group(1) != None: + # line already converted - nothing to do + newlines.append(line) + continue + midlines = [] + midlinecount = 1 + while len(lines) > 0: + nextline = lines.pop(0) + if not re.match('^\s$', nextline): + # non-blank line + if midlinecount == 0: + break + midlinecount -= 1 + midlines.append(nextline) + urlline = nextline + pos2 = oldtext1.search(urlline) + if pos2 != None: + # found it - assume that there's only one instance + newline = oldtext0.sub(newtext[0], line) + newurl = oldtext1.sub(newtext[1], urlline) + newlines.append(newline) + newlines.extend(midlines) + newlines.append(newurl) + updated += 1 + continue + else: + if updated != 0: + lineno = 1 + len(newlines) + print "Problem in " + file + " at " + lineno + ": incorrectly formatted >" + print line + print midlines + print urlline + global errorfiles + errorfiles.append(file) + break + newlines.append(line) + + if updated == 0: + print " = no change to " + file + return + + if updated > 1: + global multinoticefiles + multinoticefiles.append(file) + print '! found %d SFL notices in %s' % (updated, file) + + global shadowroot + shadowdir = os.path.join(shadowroot, dir) + if not os.path.exists(shadowdir) : + os.makedirs(shadowdir) + newfile = os.path.join(shadowroot,file) + os.rename(file, newfile) + if encoded == 'text': + f = open(file, 'w') + else: + f = codecs.open(file, 'w', encoding=encoded) + f.writelines(newlines) + f.close() + print "* updated %s (encoding %s)" % (file, f.encoding) + +# process tree + +for root, dirs, files in os.walk('epoc32', topdown=True): + if re.compile('epoc32$').match(root) >= 0: + if 'build' in dirs: + dirs.remove('build') # don't recurse into the epoc32/build subtree + for name in files: + encoding = file_type(os.path.join(root, name)) + if encoding: + map_eula(root, name, encoding) + +print '%d problem files' % len(errorfiles) +print errorfiles + +print '%d files with multiple notices' % len(multinoticefiles) +print multinoticefiles + +