CDDB-1.3/0042755000175000017500000000000007252526135010160 5ustar benbenCDDB-1.3/DiscID.py0100755000175000017500000000350307252525733011633 0ustar benben#!/usr/bin/env python # Module for fetching information about an audio compact disc and # returning it in a format friendly to CDDB. # If called from the command line, will print out disc info in a # format identical to Robert Woodcock's 'cd-discid' program. # Written 17 Nov 1999 by Ben Gertzfield # This work is released under the GNU GPL, version 2 or later. # Release version 1.3 # CVS ID: $Id: DiscID.py,v 1.9 2001/03/10 22:34:03 che_fox Exp $ import cdrom, sys def cddb_sum(n): ret = 0 while n > 0: ret = ret + (n % 10) n = n / 10 return ret def open(device=None, flags=None): # Allow this function to be called with no arguments, # specifying that we should call cdrom.open() with # no arguments. if device == None: return cdrom.open() elif flags == None: return cdrom.open(device) else: return cdrom.open(device, flags) def disc_id(device): (first, last) = cdrom.toc_header(device) track_frames = [] checksum = 0 for i in range(first, last + 1): (min, sec, frame) = cdrom.toc_entry(device, i) checksum = checksum + cddb_sum(min*60 + sec) track_frames.append(min*60*75 + sec*75 + frame) (min, sec, frame) = cdrom.leadout(device) track_frames.append(min*60*75 + sec*75 + frame) total_time = (track_frames[-1] / 75) - (track_frames[0] / 75) discid = ((checksum % 0xff) << 24 | total_time << 8 | last) return [discid, last] + track_frames[:-1] + [ track_frames[-1] / 75 ] if __name__ == '__main__': dev_name = None device = None if len(sys.argv) >= 2: dev_name = sys.argv[1] if dev_name: device = open(dev_name) else: device = open() disc_info = disc_id(device) print ('%08lx' % disc_info[0]), for i in disc_info[1:]: print ('%d' % i), CDDB-1.3/CDDB.py0100755000175000017500000000757007252525733011240 0ustar benben#!/usr/bin/env python # Module for retrieving CDDB v1 data from CDDB servers via HTTP # Written 17 Nov 1999 by Ben Gertzfield # This work is released under the GNU GPL, version 2 or later. # Release version 1.3 # CVS ID: $Id: CDDB.py,v 1.7 2001/03/10 22:34:03 che_fox Exp $ import urllib, string, socket, os, struct, re name = 'CDDB.py' version = 1.3 if os.environ.has_key('EMAIL'): (default_user, hostname) = string.split(os.environ['EMAIL'], '@') else: default_user = os.geteuid() or os.environ['USER'] or 'user' hostname = socket.gethostname() or 'host' proto = 4 default_server = 'http://freedb.freedb.org/~cddb/cddb.cgi' def query(track_info, server_url=default_server, user=default_user, host=hostname, client_name=name, client_version=version): disc_id = track_info[0] num_tracks = track_info[1] query_str = (('%08lx %d ') % (disc_id, num_tracks)) for i in track_info[2:]: query_str = query_str + ('%d ' % i) query_str = urllib.quote_plus(string.rstrip(query_str)) url = "%s?cmd=cddb+query+%s&hello=%s+%s+%s+%s&proto=%i" % \ (server_url, query_str, user, host, client_name, client_version, proto) response = urllib.urlopen(url) # Four elements in header: status, category, disc-id, title header = string.split(string.rstrip(response.readline()), ' ', 3) header[0] = string.atoi(header[0]) if header[0] == 200: # OK result = { 'category': header[1], 'disc_id': header[2], 'title': header[3] } return [ header[0], result ] elif header[0] == 211 or header[0] == 210: # multiple matches result = [] for line in response.readlines(): line = string.rstrip(line) if line == '.': # end of matches break # otherwise: # split into 3 pieces, not 4 # (thanks to bgp for the fix!) match = string.split(line, ' ', 2) result.append({ 'category': match[0], 'disc_id': match[1], 'title': match[2] }) return [ header[0], result ] else: return [ header[0], None ] def read(category, disc_id, server_url=default_server, user=default_user, host=hostname, client_name=name, client_version=version): url = "%s?cmd=cddb+read+%s+%s&hello=%s+%s+%s+%s&proto=%i" % \ (server_url, category, disc_id, user, host, client_name, client_version, proto) response = urllib.urlopen(url) header = string.split(string.rstrip(response.readline()), ' ', 3) header[0] = string.atoi(header[0]) if header[0] == 210 or header[0] == 417: # success or access denied reply = [] for line in response.readlines(): line = string.rstrip(line) if line == '.': break; line = string.replace(line, r'\t', "\t") line = string.replace(line, r'\n', "\n") line = string.replace(line, r'\\', "\\") reply.append(line) if header[0] == 210: # success, parse the reply return [ header[0], parse_read_reply(reply) ] else: # access denied. :( return [ header[0], reply ] else: return [ header[0], None ] def parse_read_reply(comments): len_re = re.compile(r'#\s*Disc length:\s*(\d+)\s*seconds') revis_re = re.compile(r'#\s*Revision:\s*(\d+)') submit_re = re.compile(r'#\s*Submitted via:\s*(.+)') keyword_re = re.compile(r'([^=]+)=(.*)') result = {} for line in comments: keyword_match = keyword_re.match(line) if keyword_match: (keyword, data) = keyword_match.groups() if result.has_key(keyword): result[keyword] = result[keyword] + data else: result[keyword] = data continue len_match = len_re.match(line) if len_match: result['disc_len'] = int(len_match.group(1)) continue revis_match = revis_re.match(line) if revis_match: result['revision'] = int(revis_match.group(1)) continue submit_match = submit_re.match(line) if submit_match: result['submitted_via'] = submit_match.group(1) continue return result CDDB-1.3/CHANGES0100644000175000017500000000431007252525733011147 0ustar benbenv1.3 ---- Phew. Lots of updating. Default to freedb.freedb.org for the CDDB server; I don't want to play GraceNote's licensing games. FreeDB is great and works perfectly. New cdrom.open() and wrapper DiscID.open() calls to perform "do what I mean" CD audio device opening appropriate to each platform; even works on Win32. Update win32/mci.dll for Python 2.0; thanks to Mike Roberts for the recompile! Also, remove all occurences of 'import fcntl', as it's no longer necessary with the new DiscID.open() call. Tested and works on Windows 2000 with Python 2.0. Update cddb-info.py to reflect the new simple DiscID.open() call. Update setup.py to use the new Extension module instead of the old way for specifying which C files to compile. Update win32/cdrom.py to add a cdrom.open() call. Since win32 does not use an open file for the audio cdrom, just returns the "device" string passed in. The default of cdaudio should be fine for most people, but I assume there are alternate "device" names. Update unix/cdrommodule.c to add a cdrom.open() call. Uses #define'd defaults appropriate to each platform for both the CDROM device file name (/dev/cdrom on bsd/linux, /dev/vol/alias/cdrom0 on Solaris) and the flags to use (O_RDONLY | O_NONBLOCK on Linux). Add setup-win.py, experimental win32 setup.py. Untested. v1.2 ---- OpenBSD support by "Alexander S . Guy" . Thanks! Hopefully now that Python 1.6 has been released, distutils will start to be used. I haven't tested this version under 1.6 yet, but I assume it will still work. v1.1 ---- Fixes for odd cases under recent-ish Linux kernels, whereby the cdrom driver wants programs to open the device in mode O_RDONLY | O_NONBLOCK if they're reading audio tracks. Fix for when running DiscID.py from command line, was passing in name of device rather than opened device previously (how embarassing!) v1.0 ---- First full 1.0 release. Fixed several bugs related to multiple match returns from CDDB in CDDB.py and cddb-info.py. cdrom module now supports FreeBSD, Linux, Solaris, and Win32. Provide setup.py for when distutils starts being used. v0.5 ---- Initial release. Most functionality is there. cdrom module only provided for Linux. CDDB-1.3/COPYING0100644000175000017500000004312707016207002011200 0ustar benben GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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) 19yy 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) 19yy 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 Library General Public License instead of this License. CDDB-1.3/unix/0042755000175000017500000000000007252526135011143 5ustar benbenCDDB-1.3/unix/cdrommodule.c0100644000175000017500000001502307252525733013620 0ustar benben/* * cdrommodule.c * Python extension module for reading in audio CD-ROM data * * Please port me to other OSes besides Linux, Solaris, OpenBSD, * and FreeBSD! * * See the README for info. * * Written 17 Nov 1999 by Ben Gertzfield * This work is released under the GNU GPL, version 2 or later. * * FreeBSD support by Michael Yoon * OpenBSD support added by Alexander Guy * * Thanks to Viktor Fougstedt for info * on the include file to make this work on Solaris! * * Release version 1.2 * CVS ID: $Id: cdrommodule.c,v 1.5 2001/03/10 22:34:03 che_fox Exp $ */ #include "Python.h" #include #include #ifdef __linux__ #include #endif #if defined(sun) || defined(__FreeBSD__) || defined(__OpenBSD__) #include #endif /* * Since FreeBSD has identical support but different names for lots * of these structs and constants, we'll just #define CDDB_WHATEVER * so that we don't have to repeat the code. */ #ifdef __FreeBSD__ #define CDDB_TOC_HEADER_STRUCT ioc_toc_header #define CDDB_STARTING_TRACK_FIELD starting_track #define CDDB_ENDING_TRACK_FIELD ending_track #define CDDB_READ_TOC_HEADER_FLAG CDIOREADTOCHEADER #define CDDB_TOC_ENTRY_STRUCT ioc_read_toc_single_entry #define CDDB_TRACK_FIELD track #define CDDB_FORMAT_FIELD address_format #define CDDB_MSF_FORMAT CD_MSF_FORMAT #define CDDB_ADDR_FIELD entry.addr #define CDDB_READ_TOC_ENTRY_FLAG CDIOREADTOCENTRY #define CDDB_CDROM_LEADOUT 0xaa #define CDDB_DEFAULT_CDROM_DEVICE "/dev/cdrom" #define CDDB_DEFAULT_CDROM_FLAGS 0 #elif defined(__OpenBSD__) #define CDDB_TOC_HEADER_STRUCT ioc_toc_header #define CDDB_STARTING_TRACK_FIELD starting_track #define CDDB_ENDING_TRACK_FIELD ending_track #define CDDB_READ_TOC_HEADER_FLAG CDIOREADTOCHEADER #define CDDB_TOC_ENTRY_STRUCT ioc_read_toc_entry #define CDDB_TRACK_FIELD starting_track #define CDDB_FORMAT_FIELD address_format #define CDDB_MSF_FORMAT CD_MSF_FORMAT #define CDDB_ADDR_FIELD data->addr #define CDDB_READ_TOC_ENTRY_FLAG CDIOREADTOCENTRIES #define CDDB_CDROM_LEADOUT 0xaa #define CDDB_DEFAULT_CDROM_DEVICE "/dev/cdrom" #define CDDB_DEFAULT_CDROM_FLAGS 0 #else /* Linux and Solaris */ #define CDDB_TOC_HEADER_STRUCT cdrom_tochdr #define CDDB_STARTING_TRACK_FIELD cdth_trk0 #define CDDB_ENDING_TRACK_FIELD cdth_trk1 #define CDDB_READ_TOC_HEADER_FLAG CDROMREADTOCHDR #define CDDB_TOC_ENTRY_STRUCT cdrom_tocentry #define CDDB_TRACK_FIELD cdte_track #define CDDB_FORMAT_FIELD cdte_format #define CDDB_MSF_FORMAT CDROM_MSF #define CDDB_ADDR_FIELD cdte_addr #define CDDB_READ_TOC_ENTRY_FLAG CDROMREADTOCENTRY #define CDDB_CDROM_LEADOUT CDROM_LEADOUT #ifdef sun #define CDDB_DEFAULT_CDROM_DEVICE "/dev/vol/alias/cdrom0" #else #define CDDB_DEFAULT_CDROM_DEVICE "/dev/cdrom" #endif /* sun */ #define CDDB_DEFAULT_CDROM_FLAGS O_RDONLY | O_NONBLOCK #endif /* __FreeBSD__ */ static PyObject *cdrom_error; static PyObject *cdrom_toc_header(PyObject *self, PyObject *args) { struct CDDB_TOC_HEADER_STRUCT hdr; PyObject *cdrom_fileobj; int cdrom_fd; if (!PyArg_ParseTuple(args, "O!", &PyFile_Type, &cdrom_fileobj)) return NULL; cdrom_fd = fileno(PyFile_AsFile(cdrom_fileobj)); if (ioctl(cdrom_fd, CDDB_READ_TOC_HEADER_FLAG, &hdr) < 0) { PyErr_SetFromErrno(cdrom_error); return NULL; } return Py_BuildValue("bb", hdr.CDDB_STARTING_TRACK_FIELD, hdr.CDDB_ENDING_TRACK_FIELD); } static PyObject *cdrom_toc_entry(PyObject *self, PyObject *args) { struct CDDB_TOC_ENTRY_STRUCT entry; PyObject *cdrom_fileobj; int cdrom_fd; unsigned char track; #if defined(__OpenBSD__) struct cd_toc_entry data; #endif if (!PyArg_ParseTuple(args, "O!b", &PyFile_Type, &cdrom_fileobj, &track)) return NULL; cdrom_fd = fileno(PyFile_AsFile(cdrom_fileobj)); entry.CDDB_TRACK_FIELD = track; entry.CDDB_FORMAT_FIELD = CDDB_MSF_FORMAT; #if defined(__OpenBSD__) entry.data = &data; entry.data_len = sizeof(data); #endif if (ioctl(cdrom_fd, CDDB_READ_TOC_ENTRY_FLAG, &entry) < 0) { PyErr_SetFromErrno(cdrom_error); return NULL; } return Py_BuildValue("bbb", entry.CDDB_ADDR_FIELD.msf.minute, entry.CDDB_ADDR_FIELD.msf.second, entry.CDDB_ADDR_FIELD.msf.frame); } static PyObject *cdrom_leadout(PyObject *self, PyObject *args) { struct CDDB_TOC_ENTRY_STRUCT entry; PyObject *cdrom_fileobj; int cdrom_fd; #if defined(__OpenBSD__) struct cd_toc_entry data; #endif if (!PyArg_ParseTuple(args, "O!", &PyFile_Type, &cdrom_fileobj)) return NULL; cdrom_fd = fileno(PyFile_AsFile(cdrom_fileobj)); entry.CDDB_TRACK_FIELD = CDDB_CDROM_LEADOUT; entry.CDDB_FORMAT_FIELD = CDDB_MSF_FORMAT; #if defined(__OpenBSD__) entry.data = &data; entry.data_len = sizeof(data); #endif if (ioctl(cdrom_fd, CDDB_READ_TOC_ENTRY_FLAG, &entry) < 0) { PyErr_SetFromErrno(cdrom_error); return NULL; } return Py_BuildValue("bbb", entry.CDDB_ADDR_FIELD.msf.minute, entry.CDDB_ADDR_FIELD.msf.second, entry.CDDB_ADDR_FIELD.msf.frame); } int cdrom_close(FILE *cdrom_file) { return fclose(cdrom_file); } static PyObject* cdrom_open(PyObject *self, PyObject *args) { int cdrom_fd; FILE *cdrom_file; char *cdrom_device = CDDB_DEFAULT_CDROM_DEVICE; int cdrom_open_flags = CDDB_DEFAULT_CDROM_FLAGS; PyObject *cdrom_file_object; if (!PyArg_ParseTuple(args, "|si", &cdrom_device, &cdrom_open_flags)) return NULL; cdrom_fd = open(cdrom_device, cdrom_open_flags); if (cdrom_fd == -1) { PyErr_SetFromErrno(cdrom_error); return NULL; } cdrom_file = fdopen(cdrom_fd, "r"); if (cdrom_file == NULL) { PyErr_SetFromErrno(cdrom_error); return NULL; } cdrom_file_object = PyFile_FromFile(cdrom_file, cdrom_device, "r", cdrom_close); if (cdrom_file_object == NULL) { PyErr_SetString(cdrom_error, "Internal conversion from file pointer to Python object failed"); fclose(cdrom_file); return NULL; } return Py_BuildValue("O", cdrom_file_object); } static PyMethodDef cdrom_methods[] = { { "toc_header", cdrom_toc_header, METH_VARARGS }, { "toc_entry", cdrom_toc_entry, METH_VARARGS }, { "leadout", cdrom_leadout, METH_VARARGS}, { "open", cdrom_open, METH_VARARGS}, { NULL, NULL } }; void initcdrom(void) { PyObject *module, *dict; module = Py_InitModule("cdrom", cdrom_methods); dict = PyModule_GetDict(module); cdrom_error = PyErr_NewException("cdrom.error", NULL, NULL); PyDict_SetItemString(dict, "error", cdrom_error); } CDDB-1.3/Makefile.pre.in0100644000175000017500000002322007015347255013005 0ustar benben# Universal Unix Makefile for Python extensions # ============================================= # Short Instructions # ------------------ # 1. Build and install Python (1.5 or newer). # 2. "make -f Makefile.pre.in boot" # 3. "make" # You should now have a shared library. # Long Instructions # ----------------- # Build *and install* the basic Python 1.5 distribution. See the # Python README for instructions. (This version of Makefile.pre.in # only withs with Python 1.5, alpha 3 or newer.) # Create a file Setup.in for your extension. This file follows the # format of the Modules/Setup.in file; see the instructions there. # For a simple module called "spam" on file "spammodule.c", it can # contain a single line: # spam spammodule.c # You can build as many modules as you want in the same directory -- # just have a separate line for each of them in the Setup.in file. # If you want to build your extension as a shared library, insert a # line containing just the string # *shared* # at the top of your Setup.in file. # Note that the build process copies Setup.in to Setup, and then works # with Setup. It doesn't overwrite Setup when Setup.in is changed, so # while you're in the process of debugging your Setup.in file, you may # want to edit Setup instead, and copy it back to Setup.in later. # (All this is done so you can distribute your extension easily and # someone else can select the modules they actually want to build by # commenting out lines in the Setup file, without editing the # original. Editing Setup is also used to specify nonstandard # locations for include or library files.) # Copy this file (Misc/Makefile.pre.in) to the directory containing # your extension. # Run "make -f Makefile.pre.in boot". This creates Makefile # (producing Makefile.pre and sedscript as intermediate files) and # config.c, incorporating the values for sys.prefix, sys.exec_prefix # and sys.version from the installed Python binary. For this to work, # the python binary must be on your path. If this fails, try # make -f Makefile.pre.in Makefile VERSION=1.5 installdir= # where is the prefix used to install Python for installdir # (and possibly similar for exec_installdir=). # Note: "make boot" implies "make clobber" -- it assumes that when you # bootstrap you may have changed platforms so it removes all previous # output files. # If you are building your extension as a shared library (your # Setup.in file starts with *shared*), run "make" or "make sharedmods" # to build the shared library files. If you are building a statically # linked Python binary (the only solution of your platform doesn't # support shared libraries, and sometimes handy if you want to # distribute or install the resulting Python binary), run "make # python". # Note: Each time you edit Makefile.pre.in or Setup, you must run # "make Makefile" before running "make". # Hint: if you want to use VPATH, you can start in an empty # subdirectory and say (e.g.): # make -f ../Makefile.pre.in boot srcdir=.. VPATH=.. # === Bootstrap variables (edited through "make boot") === # The prefix used by "make inclinstall libainstall" of core python installdir= /usr/local # The exec_prefix used by the same exec_installdir=$(installdir) # Source directory and VPATH in case you want to use VPATH. # (You will have to edit these two lines yourself -- there is no # automatic support as the Makefile is not generated by # config.status.) srcdir= . VPATH= . # === Variables that you may want to customize (rarely) === # (Static) build target TARGET= python # Installed python binary (used only by boot target) PYTHON= python # Add more -I and -D options here CFLAGS= $(OPT) -I$(INCLUDEPY) -I$(EXECINCLUDEPY) $(DEFS) # These two variables can be set in Setup to merge extensions. # See example[23]. BASELIB= BASESETUP= # === Variables set by makesetup === MODOBJS= _MODOBJS_ MODLIBS= _MODLIBS_ # === Definitions added by makesetup === # === Variables from configure (through sedscript) === VERSION= @VERSION@ CC= @CC@ LINKCC= @LINKCC@ SGI_ABI= @SGI_ABI@ OPT= @OPT@ LDFLAGS= @LDFLAGS@ LDLAST= @LDLAST@ DEFS= @DEFS@ LIBS= @LIBS@ LIBM= @LIBM@ LIBC= @LIBC@ RANLIB= @RANLIB@ MACHDEP= @MACHDEP@ SO= @SO@ LDSHARED= @LDSHARED@ CCSHARED= @CCSHARED@ LINKFORSHARED= @LINKFORSHARED@ #@SET_CCC@ # Install prefix for architecture-independent files prefix= /usr/local # Install prefix for architecture-dependent files exec_prefix= $(prefix) # === Fixed definitions === # Shell used by make (some versions default to the login shell, which is bad) SHELL= /bin/sh # Expanded directories BINDIR= $(exec_installdir)/bin LIBDIR= $(exec_prefix)/lib MANDIR= $(installdir)/man INCLUDEDIR= $(installdir)/include SCRIPTDIR= $(prefix)/lib # Detailed destination directories BINLIBDEST= $(LIBDIR)/python$(VERSION) LIBDEST= $(SCRIPTDIR)/python$(VERSION) INCLUDEPY= $(INCLUDEDIR)/python$(VERSION) EXECINCLUDEPY= $(exec_installdir)/include/python$(VERSION) LIBP= $(exec_installdir)/lib/python$(VERSION) DESTSHARED= $(BINLIBDEST)/site-packages LIBPL= $(LIBP)/config PYTHONLIBS= $(LIBPL)/libpython$(VERSION).a MAKESETUP= $(LIBPL)/makesetup MAKEFILE= $(LIBPL)/Makefile CONFIGC= $(LIBPL)/config.c CONFIGCIN= $(LIBPL)/config.c.in SETUP= $(LIBPL)/Setup SYSLIBS= $(LIBM) $(LIBC) ADDOBJS= $(LIBPL)/python.o config.o # Portable install script (configure doesn't always guess right) INSTALL= $(LIBPL)/install-sh -c # Shared libraries must be installed with executable mode on some systems; # rather than figuring out exactly which, we always give them executable mode. # Also, making them read-only seems to be a good idea... INSTALL_SHARED= ${INSTALL} -m 555 # === Fixed rules === # Default target. This builds shared libraries only default: sharedmods # Build everything all: static sharedmods # Build shared libraries from our extension modules sharedmods: $(SHAREDMODS) # Build a static Python binary containing our extension modules static: $(TARGET) $(TARGET): $(ADDOBJS) lib.a $(PYTHONLIBS) Makefile $(BASELIB) $(LINKCC) $(LDFLAGS) $(LINKFORSHARED) \ $(ADDOBJS) lib.a $(PYTHONLIBS) \ $(LINKPATH) $(BASELIB) $(MODLIBS) $(LIBS) $(SYSLIBS) \ -o $(TARGET) $(LDLAST) install: sharedmods if test ! -d $(DESTSHARED) ; then \ mkdir $(DESTSHARED) ; else true ; fi -for i in X $(SHAREDMODS); do \ if test $$i != X; \ then $(INSTALL_SHARED) $$i $(DESTSHARED)/$$i; \ fi; \ done # Build the library containing our extension modules lib.a: $(MODOBJS) -rm -f lib.a ar cr lib.a $(MODOBJS) -$(RANLIB) lib.a # This runs makesetup *twice* to use the BASESETUP definition from Setup config.c Makefile: Makefile.pre Setup $(BASESETUP) $(MAKESETUP) $(MAKESETUP) \ -m Makefile.pre -c $(CONFIGCIN) Setup -n $(BASESETUP) $(SETUP) $(MAKE) -f Makefile do-it-again # Internal target to run makesetup for the second time do-it-again: $(MAKESETUP) \ -m Makefile.pre -c $(CONFIGCIN) Setup -n $(BASESETUP) $(SETUP) # Make config.o from the config.c created by makesetup config.o: config.c $(CC) $(CFLAGS) -c config.c # Setup is copied from Setup.in *only* if it doesn't yet exist Setup: cp $(srcdir)/Setup.in Setup # Make the intermediate Makefile.pre from Makefile.pre.in Makefile.pre: Makefile.pre.in sedscript sed -f sedscript $(srcdir)/Makefile.pre.in >Makefile.pre # Shortcuts to make the sed arguments on one line P=prefix E=exec_prefix H=Generated automatically from Makefile.pre.in by sedscript. L=LINKFORSHARED # Make the sed script used to create Makefile.pre from Makefile.pre.in sedscript: $(MAKEFILE) sed -n \ -e '1s/.*/1i\\/p' \ -e '2s%.*%# $H%p' \ -e '/^VERSION=/s/^VERSION=[ ]*\(.*\)/s%@VERSION[@]%\1%/p' \ -e '/^CC=/s/^CC=[ ]*\(.*\)/s%@CC[@]%\1%/p' \ -e '/^CCC=/s/^CCC=[ ]*\(.*\)/s%#@SET_CCC[@]%CCC=\1%/p' \ -e '/^LINKCC=/s/^LINKCC=[ ]*\(.*\)/s%@LINKCC[@]%\1%/p' \ -e '/^OPT=/s/^OPT=[ ]*\(.*\)/s%@OPT[@]%\1%/p' \ -e '/^LDFLAGS=/s/^LDFLAGS=[ ]*\(.*\)/s%@LDFLAGS[@]%\1%/p' \ -e '/^DEFS=/s/^DEFS=[ ]*\(.*\)/s%@DEFS[@]%\1%/p' \ -e '/^LIBS=/s/^LIBS=[ ]*\(.*\)/s%@LIBS[@]%\1%/p' \ -e '/^LIBM=/s/^LIBM=[ ]*\(.*\)/s%@LIBM[@]%\1%/p' \ -e '/^LIBC=/s/^LIBC=[ ]*\(.*\)/s%@LIBC[@]%\1%/p' \ -e '/^RANLIB=/s/^RANLIB=[ ]*\(.*\)/s%@RANLIB[@]%\1%/p' \ -e '/^MACHDEP=/s/^MACHDEP=[ ]*\(.*\)/s%@MACHDEP[@]%\1%/p' \ -e '/^SO=/s/^SO=[ ]*\(.*\)/s%@SO[@]%\1%/p' \ -e '/^LDSHARED=/s/^LDSHARED=[ ]*\(.*\)/s%@LDSHARED[@]%\1%/p' \ -e '/^CCSHARED=/s/^CCSHARED=[ ]*\(.*\)/s%@CCSHARED[@]%\1%/p' \ -e '/^$L=/s/^$L=[ ]*\(.*\)/s%@$L[@]%\1%/p' \ -e '/^$P=/s/^$P=\(.*\)/s%^$P=.*%$P=\1%/p' \ -e '/^$E=/s/^$E=\(.*\)/s%^$E=.*%$E=\1%/p' \ $(MAKEFILE) >sedscript echo "/^#@SET_CCC@/d" >>sedscript echo "/^installdir=/s%=.*%= $(installdir)%" >>sedscript echo "/^exec_installdir=/s%=.*%=$(exec_installdir)%" >>sedscript echo "/^srcdir=/s%=.*%= $(srcdir)%" >>sedscript echo "/^VPATH=/s%=.*%= $(VPATH)%" >>sedscript echo "/^LINKPATH=/s%=.*%= $(LINKPATH)%" >>sedscript echo "/^BASELIB=/s%=.*%= $(BASELIB)%" >>sedscript echo "/^BASESETUP=/s%=.*%= $(BASESETUP)%" >>sedscript # Bootstrap target boot: clobber VERSION=`$(PYTHON) -c "import sys; print sys.version[:3]"`; \ installdir=`$(PYTHON) -c "import sys; print sys.prefix"`; \ exec_installdir=`$(PYTHON) -c "import sys; print sys.exec_prefix"`; \ $(MAKE) -f $(srcdir)/Makefile.pre.in VPATH=$(VPATH) srcdir=$(srcdir) \ VERSION=$$VERSION \ installdir=$$installdir \ exec_installdir=$$exec_installdir \ Makefile # Handy target to remove intermediate files and backups clean: -rm -f *.o *~ # Handy target to remove everything that is easily regenerated clobber: clean -rm -f *.a tags TAGS config.c Makefile.pre $(TARGET) sedscript -rm -f *.so *.sl so_locations # Handy target to remove everything you don't want to distribute distclean: clobber -rm -f Makefile Setup CDDB-1.3/README0100644000175000017500000003004407252525733011037 0ustar benbenREADME for CDDB.py and DiscID.py, version 1.3 Copyright (C) 1999, 2000 Ben Gertzfield -------------------------------------------------------- The dynamic duo of CDDB.py and DiscID.py, along with their side-kick C module cdrommodule.so, provide an easy way for Python programs to fetch information on audio CDs from CDDB (http://www.cddb.com/) -- a very large online database of track listings and other information on audio CDs. UNIX platforms and Windows are both supported. This work is released under the GNU GPL; see the file COPYING for more information. Note that for CDDB.py version 1.3 and later, the default CDDB servers have changed to FreeDB, as GraceNote, the owners of the previously-free CDDB archives, have become unreasonably restrictive with access to their database. See http://www.freedb.org/ for more information on FreeDB. The old CDDB servers are still usable, but GraceNote has banned all "non-registered" programs -- including CDDB.py -- from accessing their databases. I'm not particularly interested in bending over backwards for them, but CDDB.query() can still access any CDDB host you specify, and from version 1.3 on, also allows you to 'fake' the identification string to anything you wish for accessing their servers. ----- If you are using Python 1.6 or 2.0 on Linux, FreeBSD, OpenBSD, or Solaris, installing is simple. As root, run: # python setup.py install (This also works if you have installed Distutils on an older Python. See http://www.python.org/sigs/distutils-sig/download.html for more information.) ----- If you have an older version of Python installed on Linux, FreeBSD, OpenBSD, or Solaris: % make -f Makefile.pre.in boot % make Then copy CDDB.py, DiscID,py, and cdrommodule.so to your local Python packages directory (usually /usr/lib/python1.5/site-packages). ----- If you are using Python 2.0 on Windows, you can simply extract the following files to your C:\Python20\Lib\ directory: CDDB.py DiscID.py win32\cdrom.py win32\mci.dll Older revisions of Python will require a by-hand recompile of win32\mci.c; win32\mci.dsp has been provided for Visual C++ users. I do not have access to a Windows compiler, so I cannot support the module very well. However, I have tested that it works on Windows 2000 with Python 2.0. Thanks to Mike Roberts for recompiling the mci.dll library for Python 2.0! There is an experimental setup-win32.py Distutils, which (in theory) works the same as the *nix method (python setup-win32.py install) on Windows. Completely untested. ----- The distribution is split up into three parts: * CDDB.py, for querying the online CDDB servers. * cdrommodule.so, a C extension module, for actually querying the CD-ROM drive for the track start times and other data. * DiscID.py, a wrapper around cdrommodule.so, which formats the track data the way the CDDB protocol requires it. Also included is cddb-info.py, a quick example of how to use CDDB.py and DiscID.py together to fetch the track info of an audio CD. Feel free to use this to understand how to make your own Python CDDB applications! For another example as to how CDDB.py works, see Russ Nelson's MP3 renamer program: http://russnelson.com/rename-tracks DiscID.py --------- The DiscID.py module is a platform-independant wrapper around the cdrommodule.so C extension, and is used to get the track information of an audio CD into the format the CDDB protocol requires. There are two methods of the DiscID module that are of interest: device = DiscID.open() This is the default, cross-platform way to open the audio CD-ROM device. The device defaults to /dev/cdrom on Linux and BSD, /dev/vol/alias/cdrom0 on Solaris, and cdaudio under Windows. You do not have to use this function to open the audio CD-ROM device, but it's a sane default. If you want to specify a different device name or flags for opening, use the following: device = DiscID.open(devicename, flags) The optional flags parameter should be an int under *nix, and a string under Windows. Flags come from the fcntl module under *nix. disc_id = DiscID.disc_id(device) Given an opened file object corresponding to a CD-ROM device (either opened by hand, or returned from DiscID.open above), return an array of the format: [cddb_checksum, num_tracks, num_frames 1, ... num_frames n, num_seconds] cddb_checksum is the 128-bit checksum of the track information, as specified by CDDB num_tracks is the number of tracks on the disc num_frames x is the offset of the start of track x, in terms of frames. A frame is simply 1/75th of a second. x ranges from 1 to num_tracks. num_seconds is the total number of seconds on the disc, as measured by the start of the special 'lead-out' track. The disc_id returned from DiscID.disc_id may look complex, but it's exactly in the format CDDB wants, and is the format needed for CDDB.query(disc_id), as described below. CDDB.py ------- The CDDB.py module is platform-independant; its job is to query the online CDDB servers via HTTP and retrieve track listings and any other data relevant to the specified audio CD. There are two methods of the CDDB module that are of interest: (status, info) = CDDB.query(disc_id, [server_url], [user], [host], [client_name], [client_version]) Given a disc_id, as returned from DiscID.disc_id() above, return a tuple of two items. The first item returned is an integer indicating the status returned from the server; it will be one of the following: * 200: Success * 211: Multiple inexact matches were found * 210: Multiple exact matches were found * 202: No match found * 403: Error; database entry is corrupt * 409: Error; no handshake. (client-side error?) Any other return code is failure due to a server or client error. The actual contents of the second item returned depend on the status returned by the server. On 200, a dictionary containing three items is returned: info['category']: The category the audio CD belongs in info['disc_id']: The CDDB checksum disc ID of the given disc info['title']: The title of the audio CD On 211 or 210, a list will be returned as the second item. Each element of the list will be a dictionary containing three items, exactly the same as a single 200 success return. On any other status, None will be returned as the second item. By default, the server http://freedb.freedb.org/~cddb/cddb.cgi will be used. You can specify a different server URL as the second argument to CDDB.query(). The identification string used to tell the CDDB servers what program is accessing them defaults to CDDB.py, but you can change that by specifying different client_name and client_version arguments to CDDB.query(). The optional user and host arguments are sent in the 'hello' portion of the CDDB query. They should correspond to the user's email address (if you believe in the CDDB docs, that is -- it may not be nice to send the user's email address without asking them!) By default, if the EMAIL environment variable is set, user and host will be set by parsing $EMAIL into user@host. Otherwise, user will default to os.geteuid(), falling back to os.environ['USER'], then just plain 'user', and host will default to socket.gethostname() or just plain 'host' if that fails. (status, info) = CDDB.read(category, disc_id, [server_url], [user], [host], [client_name], [client_version]) Given a category and a disc ID checksum as returned from CDDB.query(), return a tuple of two items. The first item returned is an integer indicating the status, as above. It will be one of the following: * 210: Success * 401: Specified entry not found * 402: Server error * 403: Database entry is corrupt * 409: No handshake * 417: Access limit exceeded Any other return value is a server or client error. The second value returned from CDDB.read() depends on the status returned by the server. On 210, a dictionary will be returned, the keys of which follow the keywords returned by the CDDB read command. Dictionary entries that will be of inter est: info['TTITLE#'] (where # ranges from 1 to the last track on the disc): The title of track number #. Note that this is not padded on the left with zeroes. info['DTITLE'] The title of the disc. info['EXTD'] Extended data on the CD. (credits, etc.) info['EXTT#'] Extended data on track number #. info['submitted_via'] Optional; name of the client that submitted the data for this disc info['revision'] Optional; revision of this CDDB entry Note that aside from TTITLE#, most of these fields will be empty strings for most discs. Also, submitted_via and revision are technically in the comments returned from the server, so may or may not even be there. Test first! As with CDDB.query(), server_url, user, host, client_name, and client_version are all optional. See above for the defaults. cdrommodule.so -------------- This is the platform-specific part of the trio. I have included unix/cdrommodule.c, which implements the necessary functions under Linux, FreeBSD, OpenBSD, and Solaris, but the interface is intended to be easy enough to implement on any platform. If you want to write your own cdrommodule.so for your platform, here are the functions you'll need to export: device = cdrom.open([device], [flags]) If given no arguments, perform the proper platform-specific steps to open the default CDROM audio device and return an opened Python file object corresponding to it. If called with one argument, override the default CDROM audio device with this argument. If called with two arguments, open the device with the specified flags (integer on *nix, string on Windows.) On Windows, which does not use an opened file object to represent the CDROM audio device, returning a string describing the device is acceptable, as the other functions will just use that instead of the opened file. (first, last) = cdrom.toc_header(file) Given an open file object corresponding to a CD-ROM device, return a tuple of two integer values, (first, last). These are the track numbers of the first and last tracks, respectively. (min, sec, frame) = cdrom.toc_entry(file, track) Given an open file object and a track number, return a tuple of three integer values, (minute, second, frame). These correspond to the start time of the track, as given in MSF form. Note that a frame is simply 1/75th of a second. (min, sec, frame) = cdrom.leadout(file) Given an open file object, return a tuple of three integer values, (minute, second, frame). These correspond to the start time of the special 'leadout' track, generally track 0xAA, as given in MSF form. If your platform (i.e. Windows) cannot return this leadout track's time directly, you'll need to calculate it by taking the starting position of the last track and adding the length of the last track onto that. Watch out, because Windows' awful interface returns the length of the last track as one frame short of the real value! Note that I throw the exception 'cdrom.error' upon an error; you should stick to throwing that if your ioctls (or whatever your platform uses) fail, so we can stay consistant. It's relatively easy to write your own cdrommodule.so for whatever platform you're on. Look at unix/cdrommodule.c for hints. If you end up doing it and you'd like to have your module included in the source distribution, just contact me at the email address above. Thanks to Viktor Fougstedt for the porting information for Solaris, and Michael Yoon for the FreeBSD port! Also, thanks to Frank David for the win32 port. Note that this email address seems to be gone; I have no more contact with Frank. Mike Roberts has been extremely helpful in providing an updated mci.dll for Python 2.0; thank you, Mike! And thanks to Alexander S . Guy for the OpenBSD patch. CDDB-1.3/Setup.in0100644000175000017500000000054407077414454011613 0ustar benben# Setup.in file for the CDDB Python module # Please uncomment the lines that pertain to your OS! *shared* # For Win32, you'll just need to copy the files 'win32/mci.dll' and # 'win32/cdrom.py' to your Python module path by hand, or re-build # the mci.dll file using the mci.dsp project file. # Linux, FreeBSD, or Solaris module cdrom unix/cdrommodule.c CDDB-1.3/cddb-info.py0100755000175000017500000000255307252525733012365 0ustar benben#!/usr/bin/env python # Example of how to use CDDB.py and DiscID.py # Written 17 Nov 1999 by Ben Gertzfield = 2: dev = sys.argv[1] if dev: cdrom = DiscID.open(dev) else: cdrom = DiscID.open() print "Getting disc id in CDDB format...", disc_id = DiscID.disc_id(cdrom) print "Disc ID: %08lx Num tracks: %d" % (disc_id[0], disc_id[1]) print "Querying CDDB for info on disc...", (query_stat, query_info) = CDDB.query(disc_id) if query_stat == 200: print ("success!\nQuerying CDDB for track info of `%s'... " % query_info['title']), (read_stat, read_info) = CDDB.read(query_info['category'], query_info['disc_id']) if read_stat == 210: print "success!" # Start from 0, not 1 # thanks to bgp for the fix! for i in range(0, disc_id[1]): print "Track %.02d: %s" % (i+1, read_info['TTITLE' + `i`]) else: print "failure getting track info, status: %i" % read_stat elif query_stat == 210 or query_stat == 211: print "multiple matches found! Matches are:" for i in query_info: print "ID: %s Category: %s Title: %s" % \ (i['disc_id'], i['category'], i['title']) else: print "failure getting disc info, status %i" % query_stat CDDB-1.3/setup-win32.py0100644000175000017500000000135307252525733012632 0ustar benben#!/usr/bin/env python """Setup script for the CDDB module distribution under Win32.""" __revision__ = "$Id: setup-win32.py,v 1.1 2001/03/10 22:34:03 che_fox Exp $" from distutils.core import setup, Extension setup (# Distribution meta-data name = "CDDB", version = "1.3", description = "Module for retrieving track information about audio CDs from CDDB", author = "Ben Gertzfield", author_email = "che@debian.org", url = "http://csl.cse.ucsc.edu/~ben/python/", # Description of the modules and packages in the distribution py_modules = ['CDDB', 'DiscID', 'win32/cdrom'], ext_modules = [ Extension('mci', ['win32/mci.c']) ], # data_files = [('', ['win32/mci.dll'])] ) CDDB-1.3/setup.py0100644000175000017500000000124307252525733011670 0ustar benben#!/usr/bin/env python """Setup script for the CDDB module distribution.""" __revision__ = "$Id: setup.py,v 1.4 2001/03/10 22:34:03 che_fox Exp $" from distutils.core import setup, Extension setup (# Distribution meta-data name = "CDDB", version = "1.3", description = "Module for retrieving track information about audio CDs from CDDB", author = "Ben Gertzfield", author_email = "che@debian.org", url = "http://csl.cse.ucsc.edu/~ben/python/", # Description of the modules and packages in the distribution py_modules = ['CDDB', 'DiscID'], ext_modules = [ Extension('cdrom', ['unix/cdrommodule.c']) ] ) CDDB-1.3/win32/0042755000175000017500000000000007252526136011123 5ustar benbenCDDB-1.3/win32/cdrom.py0100644000175000017500000000371107252525733012600 0ustar benben#!/usr/bin/env python # Supporting Ben Gertzfield's cdrom-Interface using mciSendString on WIN32 # Frank David # This work is released under the GNU GPL, version 2 or later. import mci import string def toc_header(device): return (1, string.atoi(mci.mciSendString("status %s number of tracks" % device))) def toc_entry(device, track): mci.mciSendString("set %s time format msf" % device) mciString = "status %s position track %i" % (device, track) resultStr = mci.mciSendString(mciString) result = string.split(resultStr, ':', 2) r = [] for i in result: r.append(string.atoi(i)) return r def toc_entry_pos(device, track): return toc_entry(device, track) def toc_entry_len(device, track): mci.mciSendString("set %s time format msf" % device) mciString = "status %s length track %i" % (device, track) resultStr = mci.mciSendString(mciString) result = string.split(resultStr, ':', 2) r = [] for i in result: r.append(string.atoi(i)) return r def leadout(device): firstTrack, lastTrack = toc_header(device) trackPosMin, trackPosSecond, trackPosFrame = toc_entry_pos(device, lastTrack) trackLenMin, trackLenSecond, trackLenFrame = toc_entry_len(device, lastTrack) # calculate raw leadout leadoutMin, leadoutSecond, leadoutFrame = ( trackPosMin + trackLenMin, trackPosSecond + trackLenSecond, trackPosFrame + trackLenFrame) # add windows specific correction leadoutFrame = leadoutFrame + leadoutFrame # convert to minute, second, frame if leadoutFrame >= 75: leadoutFrame = leadoutFrame - 75; leadoutSecond = leadoutSecond + 1 if leadoutSecond >= 60: leadoutSecond = leadoutSecond - 60; leadoutMin = leadoutMin + 1 # return leadout as tuple return (leadoutMin, leadoutSecond, leadoutFrame) def open(device="cdaudio", flags="wait"): mci.mciSendString("open %s %s" % (device, flags)) return device CDDB-1.3/win32/mci.c0100644000175000017500000000221707077414454012040 0ustar benben#include "mci.h" #include #include #include /* * mci.c * micSendString implementation * Purpose: * Python extension module for reading in audio CD-ROM data in wi * * Written 6 Dez 1999 by Frank David */ static PyObject *mci_error; #define MCI_STRING_LEN 1000 static PyObject *mci_mciSendString(PyObject *self, PyObject *args) { char resultStr[MCI_STRING_LEN+1]; PyObject *pyStr = 0; if (!PyArg_ParseTuple(args, "O!", &PyString_Type, &pyStr)) return NULL; // winows mciSendString see cdrom.py for Samples (or MSDN for complete doc) mciSendString( PyString_AsString(pyStr), resultStr,MCI_STRING_LEN,0); return Py_BuildValue("s", resultStr); } static PyMethodDef mci_methods[] = { { "mciSendString", mci_mciSendString, METH_VARARGS }, { NULL, NULL } }; void initmci(void) { PyObject *module, *dict; module = Py_InitModule("mci", mci_methods); dict = PyModule_GetDict(module); mci_error = PyErr_NewException("mci.error", NULL, NULL); PyDict_SetItemString(dict, "error", mci_error); } CDDB-1.3/win32/mci.dll0100644000175000017500000013000007252525733012357 0ustar benbenMZ@ !L!This program cannot be run in DOS mode. $zypC>>>c:?*c:g; :>ta:?8:Rich>PEL M:! P``kB0fP8`.text*@P `.rdata ``@@.data`1p0p@.reloc" @B `$D$D$PQhdpR`uËL$jD$hPQ`P`T$Rh`p`ÐVhjjh0ph|p`P`jjhpp`PhhpV`0^ÐD$ `j Yt<3Ɋ %- pu 3r`X>3;u,9 ~ 9 ܚu1T[ uQYjX US]Vu W}u =&tu"\t WVSЅt WVSu3NWVS E u u7WPStu&WVSu!E } t\tWVSЉE E _^[] t u=u t$ hpYYáTthphphphpjjt$  jjj Wj_9=ut$`P`|$ S\$=ܚؚuuN@u NNC|5@8`_^[SVW@t7;s!_ {tSH`$$;r6 &Y@|_^[S39HVWu53:t<=tGV YtP6 Y;5uj Y=8t9UWH YE?=t"U ;Yuj YW62 YY8u]5 Y_^D[UQQS39HVWu0hVSL`X5К8tEPEPSSWMEMPa ;ujYEPEPEPVWEH5_^[UMESV!uW} Et7} 8"uDP@"t)t%!t tF@tՊFt&F8"uF@CtF@!t tF@ t t ūuHtfe8 t u@8t7} UE3ۀ8\u@C8"u,u%39}t x"Pu}} 39U‰UKtCt\FKutJ}u t? t:}t.t!tF@F!t@@Xt&Ft'E_^[]QQSU-``VW333;u3Ջ;t (\`;;u Ջ;f9t@@f9u@@f9u+Ƌ=X`SS@SSPVSSD$4׋;t2U;YD$t#SSUPt$$VSSׅut$Y\$\$VT`SuL;u \`;t<8t @8u@8u+@UgY;u3 UWV WP`3_^][YYVt$j&d`f8MZuHj,P,Y;Yt0@8t9;uA8uj SP tttEP}Y[3j9D$hP`(t6,u hVY uu5(`3jXá,VWufS39U-|`~@=x`p h@h6hj6vj5(ՃC;|5j5(]['u"sFthjPx`6;u5(`_^jX t u*=u!hYthYUU3ɸp;t A=@qrV;pu =\hPjL`u\hdPDYY\WP\@YWj|Yuj Yj>YWu `>gYj Y_6`^]UE4@q`]UjhdhAdPd%SVWuu u uw3;uj^u 3ۉ],uA};=w|j Y]W YEM9]t^uH3ۋu j KYÃuA;5w9j YEPmYEML9]tVSu) 9]u>Vj5(`E9]u'9htVY03ۋu j YËEMd _^[Ujh0dhAdPd%SVWu,u;j YeVYEt VPYYM}Qj =YÃuSj YEEPEPV E܅tPuu  M }uu j YVj5(|`Md _^[5ht$YYÃ|$w"t$Yu9D$tt$Yu3UjhHdhAdPd% SVW,uCu;5j YeVYEM Etmj YÃuZEtpj^u;5w.j YEP&YEM Eu-Vuj YËEujX$Pj5(`Md _^[W|$j$L$WtAt;u~Ѓ3ƒtAt#ttt͍y yyyL$ tAtdGu~Ѓ3‹tt4t'ttljD$_fD$G_fD$_ÈD$_ËL$tAt@u~Ѓ3ƒtAt2t$tt͍AL$+ÍAL$+ÍAL$+ÍAL$+USVWjuY;Y]u3pV3Ҹr9tt0B=srEPS`j^;!j@%$Y3 9u󫪉}MA;!@ej@Y3 4Rr;t,Qt%;wUr!@;vAA9uE}rEPrY$RAAyGƀ!@=rSY$5%3=PtjmY_^[ËD$%PuP%`uP%`uPËD$-t"t t Ht3øøøøWj@Y3 3$_UEVP5`3@;rEƅ t7SWU ;w+ȍA ˃BBBu_[j5$5PVPjj5VPVPV5$Gj5VPVPh5$\3ft! t! 〠 @AA;rI3ArZw!Ȁ arzw! Ȁ @;r^Ã=HujYHUWVu M};v;xur)$*Ǻr $)$*$,*))*#ъFGFGr$*I#ъFGr$*#ъFGr$*I*|*t*l*d*\*T*L*DDDDDDDDDDDDDD$*****E^_ÐE^_ÐFGE^_ÍIFGFGE^_Ðt1|9u$r $0,$+IǺr +$8+$0,H+h++F#шGNOr$0,IF#шGFGr$0,F#шGFGFGZ$0,I++++, ,,',DDDDDDDDD D DDDD$0,@,H,X,l,E^_ÐFGE^_ÍIFGFGE^_ÐFGFGFGE^_jt$t$t$U SeVW}wu=D~jPYY 8ÊAtFЀ-uuM+uFuE$wjYu$0t E 2t }w u,9uv'E"tME$ƉEtEEtE؉EE E t83_^[̍B[Í$d$3D$ST$t B8tфtQu WV ؋ ~333ƃu%t%uu^_[3ËB8t6t8t't8tt8tt^_B[ÍB^_[ÍB^_[ÍB^_[̋L$WSV|$tiqtOL$F8tt F8t u^[_3ÊF8u~at(8uĊAtf8t3^[_G^[_Ë^[_UWVSM&ً}3ˋu F3:GwtIIы[^_Q=L$r-=s+ȋą@Ph@j5(`uËL$%%j Xá  ;sT$+P r3UMSVu AW+y iDMIM11UVUU] u~J?vj?ZK;KuL sL!\D u(M!!JL! uM!YM] MS[MZU MZRSJ?vj?Z]]+u]j?u K^;vMщMJ;v;tcM q;qu@ s!tDLu&M!1K!LuM!qM qINM qINu ]}u;M\ щ^NqNqN;Nu`L MLs%}uM DD )}uJM YJꍄ ED0E 5x`H h@SQ֋  P @@HCHyCu `xuiSjp ֡pj5(|`ȡ+ȍLQHQP:E ;vmE=_^[USVWu;uM; u%MB_^[á VW3;u0DPP5W5(p`;ta hAj5(4`;ljFt*jh hWt`;ljF uvW5(|`3N>~F_^UQMSVWqA3ۅ|Cj?iZ0DE@@Jujy hhWt`up;wtƍ4;sCu0jX^;uCF;sN;Euq )u 9U }ƍ4;urq;s~;Esvu@j^X;u%C@;]s +q aq16;s)E 9U r4맍;]s +‰A aAFk+3_^[S39XVWuBhd`;tg5`hdWօXtPhtdWh`dW\֣`\tЋ؅t`tSЋt$t$t$SX_^[3̋L$ WtzVSًt$|$uuo!FGIt%t)uuQt FGt/KuD$[^_tGIuulGKu[^D$_ÉIt~Ѓ3‹tބt,tt uƉ3҉3It 3IuuD$[^_ádtt$ЅYtjX3̋T$ L$tG3D$Wr-كt+шGIuʃttGJuD$_ËD$USVWUjjhAu$]_^[]ËL$AtD$T$SVWD$PjhAd5d%D$ Xp t.;t$$t(4v L$H |uhD@Td _^[3d yAuQ R 9QuSQ SQMKCk Y[VC20XC00USVWU] E@EEEECs {ta v|tEVUkT]^] t3x<{SkVS vjDaC T{ v4롸UkjS]]_^[]UL$)APAPy]UjhdhAdPd%SVWe39=uFWWj[ShdVW`t"WWShdVW`"9}~uuYYEuuuuuu u`9} uE WWuuE$@Pu `؉];}$eĉE܃MjXËe3}܃M]9}tfSuuuju `tMWWSuu u`u;t2E t@9};uuuSuu u`3eȋMd _^[E6$e܉]MjXËe33ۃMu;tVSuuu u`t9}WWuWWuuVSh u X`;qlT$D$VJt 8t@Iu8^u+D$ËUjhdhAdPd%SVWe衐3;u>EPj^VhdV`tEPVhdVS`jXu$E;utuuu uP`9]uESSuu E @Pu`E;tc]<ǃ$UeuWSV jXËe33M;t)uVuu ju`;tuPVu`3e̋Md _^[S39tuD$a|YzT [VWV`9=`tVjoYj[t$YD$t jYV׋D$_^[UQ=tSuEaz ]}(=D~ jSYY 8Xuk8DJte E] j e ]jXMjjjQPEPh5tF tuE EM [UQEHw 8ARV58DV^teMEj eEjXM jjjQPEPjuE #E UWVu M};v;xur)$XIǺr $pH$hI$HHHH#ъFGFGr$XII#ъFGr$XI#ъFGr$XIIOIhPh^hlhhhhhhhhhhii,i>iViliiiiiiijjjBjPj\jhjjjjjjjkk"k.kDkTkdkvkkk"hghgggxggg__GLOBAL_HEAP_SELECTED__MSVCRT_HEAP_SELECTruntime error TLOSS error SING error DOMAIN error R6028 - unable to initialize heap R6027 - not enough space for lowio initialization R6026 - not enough space for stdio initialization R6025 - pure virtual function call R6024 - not enough space for _onexit/atexit table R6019 - unable to open console device R6018 - unexpected heap error R6017 - unexpected multithread lock error R6016 - not enough space for thread data abnormal program termination R6009 - not enough space for environment R6008 - not enough space for arguments R6002 - floating point not loaded Microsoft Visual C++ Runtime Library Runtime Error! Program: ...!!)""M##GetLastActivePopupGetActiveWindowMessageBoxAuser32.dllCC|DDFFH:mm:ssdddd, MMMM dd, yyyyM/d/yyPMAMDecemberNovemberOctoberSeptemberAugustJulyJuneAprilMarchFebruaryJanuaryDecNovOctSepAugJulJunMayAprMarFebJanSaturdayFridayThursdayWednesdayTuesdayMondaySundaySatFriThuWedTueMonSunSunMonTueWedThuFriSatJanFebMarAprMayJunJulAugSepOctNovDecTgh`Lg4h`fk`&j4j>hPh^hlhhhhhhhhhhii,i>iViliiiiiiijjjBjPj\jhjjjjjjjkk"k.kDkTkdkvkkk"hghgggxgggPy_BuildValueqPyString_AsStringPyArg_ParseTuple~PyString_Type5PyDict_SetItemStringAPyErr_NewExceptionPyModule_GetDictPy_InitModule4python20.dll6mciSendStringAWINMM.dllGetCommandLineAGetVersionExitProcessTerminateProcess GetCurrentProcess GetCurrentThreadIdTlsSetValueTlsAllocTlsFreeSetLastErrorTlsGetValue-GetLastErrorSetHandleCounthGetStdHandle(GetFileTypefGetStartupInfoAZDeleteCriticalSection8GetModuleFileNameAFreeEnvironmentStringsAFreeEnvironmentStringsWWideCharToMultiByteGetEnvironmentStringsGetEnvironmentStringsW:GetModuleHandleAGetEnvironmentVariableAGetVersionExAHeapDestroyHeapCreateVirtualFreeHeapFreeWriteFileInitializeCriticalSectionoEnterCriticalSectionLeaveCriticalSectionHeapAllocGetCPInfoGetACPFGetOEMCPVirtualAllocHeapReAllocSGetProcAddressLoadLibraryAWRtlUnwindMultiByteToWideCharLCMapStringALCMapStringWiGetStringTypeAlGetStringTypeWInterlockedDecrementInterlockedIncrementKERNEL32.dll M:lkkl lmci.dllinitmci3)PpmciSendStringsO!errormci.errormci c`c 4c cbbbdb,bbaalax\ayLaz=N=U=\=b=========== >3>@>N>Y>l>>>>>?"?>?S?i?p?z??????????????? 000K0f0v0|00000+1t1z1111122222 33r333x555555566)6J6P6q6{666666666677$7/797C7I777777773898W8h8{888888899&959F999999999 :%:,:0:4:8:<:@:D:H:::::: ;;0;7;<;@;D;a;;;;;;;;;;;*<0<4<8<<<<3C3R3X3h3s3333333333333444\45667771787>7H7N7S7Y7i7r77777888888*949<9B9J9S9\99999::%:+:E:K:S:b:::;!;;;;x<<<>>? ???"?(?/?4?E?a?@o005111122222333&3D3a3y3334:444 55.5A5H5Z5b5r55555$666^6y6666677(7i777H8`8g8o8t8x8|888888888999R9X9\9`9d999999::!:K:}::::::::::::::n<<<<=I====>+?c?u???P &0` 4,484D4P4\4444444pD 00040000000000001 111$1,141<1D1d1t113333385<5`8h8l8p8t8x8|888888888888888888888888888888888999 99 9$9(9,9094989<9@9D9P999CDDB-1.3/win32/mci.dsp0100644000175000017500000000753507077414454012414 0ustar benben# Microsoft Developer Studio Project File - Name="mci" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=mci - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "mci.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "mci.mak" CFG="mci - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "mci - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "mci - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "mci - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MCI_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MCI_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x407 /d "NDEBUG" # ADD RSC /l 0x407 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 !ELSEIF "$(CFG)" == "mci - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MCI_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MCI_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x407 /d "_DEBUG" # ADD RSC /l 0x407 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept !ENDIF # Begin Target # Name "mci - Win32 Release" # Name "mci - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project CDDB-1.3/win32/mci.h0100644000175000017500000000117507077414454012047 0ustar benben // The following ifdef block is the standard way of creating macros which make exporting // from a DLL simpler. All files within this DLL are compiled with the MCI_EXPORTS // symbol defined on the command line. this symbol should not be defined on any project // that uses this DLL. This way any other project whose source files include this file see // MCI_API functions as being imported from a DLL, wheras this DLL sees symbols // defined with this macro as being exported. #ifdef MCI_EXPORTS #define MCI_API __declspec(dllexport) #else #define MCI_API __declspec(dllimport) #endif MCI_API void initmci(void);