From 5e354503c2e7af39ab12e530c37e2794bc9494a9 Mon Sep 17 00:00:00 2001 From: zyp Date: Wed, 17 May 2006 14:18:20 +0000 Subject: [project @ zyp-20060517141820-307896d115926051] [project @ 38] Added support for identifying files. --- anidb.py | 36 ++++++++++---------- pyanidb/__init__.py | 96 +++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 94 insertions(+), 38 deletions(-) diff --git a/anidb.py b/anidb.py index d5c93d4..1fcda29 100644 --- a/anidb.py +++ b/anidb.py @@ -26,8 +26,10 @@ op.add_option('-p', '--password', help = 'AniDB password.', op.add_option('-r', '--recursive', help = 'Recurse into directories.', action = 'store_true', dest = 'recursive', default = False) op.add_option('-s', '--suffix', help = 'File suffix for recursive matching.', - action = 'append', dest = 'suffix', default = config['suffix'].split()) + action = 'append', dest = 'suffix', default = config.get('suffix', '').split()) +op.add_option('-i', '--identify', help = 'Identify files.', + action = 'store_true', dest = 'identify', default = False) op.add_option('-a', '--add', help = 'Add files to mylist.', action = 'store_true', dest = 'add', default = False) @@ -35,7 +37,7 @@ options, args = op.parse_args(sys.argv[1:]) # Defaults. -options.login = options.add +options.login = options.add or options.identify if options.login: if not options.username: @@ -71,8 +73,6 @@ if options.login: try: a.auth() print 'Logged in as user %s.' % (options.username) - if a.new_version: - print 'New version available.' except pyanidb.AniDBUserError: print 'Invalid username/password.' sys.exit(1) @@ -88,21 +88,23 @@ if options.login: for filename, hash in pyanidb.hash.hash_files(files): size = os.path.getsize(filename) print 'Hashed: ed2k://|file|%s|%d|%s|' % (filename, size, hash.ed2k()) + fid = (size, hash.ed2k()) - # Adding - - if options.add: - try: - while 1: - try: - a.add_hash(size, hash.ed2k()) - except pyanidb.AniDBTimeout: - print 'Connection timed out, retrying.' - continue - break + try: + # Identify + + if options.identify: + info = a.get_file(fid, ('gname', 'romaji', 'epno', 'epromaji'), True) + fid = int(info['fid']) + print '[%s] %s - %s - %s' % (info['gname'], info['romaji'], info['epno'], info['epromaji']) + # Adding + + if options.add: + a.add_file(fid, retry = True) print 'Added file: %s' % (filename) - except pyanidb.AniDBUnknownFile: - print 'Unknown file: %s' % (filename) + + except pyanidb.AniDBUnknownFile: + print 'Unknown file: %s' % (filename) # Finished. diff --git a/pyanidb/__init__.py b/pyanidb/__init__.py index 80721bf..adc7bfe 100644 --- a/pyanidb/__init__.py +++ b/pyanidb/__init__.py @@ -2,7 +2,7 @@ import socket, time protover = 3 client = 'pyanidb' -clientver = 3 +clientver = 0 states = { 'unknown': 0, @@ -10,8 +10,22 @@ states = { 'cd': 2, 'deleted': 3, 'shared': 4, - 'release': 5 -} + 'release': 5} + +fcode = ( + '', 'aid', 'eid', 'gid', 'lid', '', '', '', + 'state', 'size', 'ed2k', 'md5', 'sha1', 'crc32', '', '', + 'dublang', 'sublang', 'quality', 'source', 'acodec', 'abitrate', 'vcodec', 'vbitrate', + 'vres', 'filetype', 'length', 'description', '', '', '', '') + +acode = ( + 'gname', 'gtag', '', '', '', '', '', '', + 'epno', 'epname', 'epromaji', 'epkanji', '', '', '', '', + 'eptotal', 'eplast', 'year', 'type', 'romaji', 'kanji', 'english', 'other', + 'short', 'synonym', 'category', '', '', '', '', '') + +info = fcode + acode +info = dict([(info[i], 1 << i) for i in xrange(len(info)) if info[i]]) class AniDBError(Exception): pass @@ -41,40 +55,56 @@ class AniDB: self.server = server self.session = '' self.lasttime = 0 - self.new_version = False + def __del__(self): self.logout() self.sock.close() - def execute(self, data): - t = time.time() - if t < self.lasttime + 2: - time.sleep(self.lasttime + 2 - t) - self.lasttime = time.time() - self.sock.sendto(data + '\n', self.server) - try: - data = self.sock.recv(8192).split('\n') - except socket.timeout: - raise AniDBTimeout() + + def newver_msg(self): + print 'New version available.' + + def retry_msg(self): + print 'Connection timed out, retrying.' + + def execute(self, data, retry = False): + while 1: + t = time.time() + if t < self.lasttime + 2: + time.sleep(self.lasttime + 2 - t) + self.lasttime = time.time() + self.sock.sendto(data + '\n', self.server) + try: + data = self.sock.recv(8192).split('\n') + except socket.timeout: + if retry: + self.retry_msg() + else: + raise AniDBTimeout() + else: + break code, text = data[0].split(' ', 1) - data = data[1:-1] + data = [line.split('|') for line in data[1:-1]] code = int(code) return code, text, data + def ping(self): t = time.time() try: return self.execute('PING')[0] == 300 and time.time() - t or None except AniDBTimeout: return None + def auth(self): code, text, data = self.execute('AUTH user=%s&pass=%s&protover=%d&client=%s&clientver=%d' % (self.username, self.password, protover, client, clientver)) if code in [200, 201]: self.session = text.split(' ', 1)[0] - if code == 201: - self.new_version = True + if code == 201 and clientver: + self.newver_msg() elif code == 500: raise AniDBUserError() else: raise AniDBReplyError(code, text) + def logout(self): if self.session: try: @@ -82,14 +112,38 @@ class AniDB: self.session = '' except AniDBError: pass - def add_hash(self, size, ed2k, state = states['hdd'], viewed = False, source = '', storage = '', other = ''): + + def get_file(self, fid, info_codes, retry = False): + try: + fid = 'size=%d&ed2k=%s' % fid + except TypeError: + fid = 'fid=%d' % (fid) + info_codes = list(info_codes) + info_codes.sort(lambda x, y: cmp(info[x], info[y])) + info_code = sum([info[code] for code in info_codes]) + code, text, data = self.execute('FILE s=%s&%s&fcode=%d&acode=%d' % (self.session, fid, info_code & 0xffffffff, info_code >> 32), retry) + if code == 220: + return dict([(name, data[0].pop(0)) for name in ['fid'] + info_codes]) + elif code == 320: + raise AniDBUnknownFile() + elif code in [501, 506]: + self.auth() + else: + raise AniDBReplyError(code, text) + return code, text, data + + def add_file(self, fid, state = 'hdd', viewed = False, source = '', storage = '', other = '', retry = False): + try: + fid = 'size=%d&ed2k=%s' % fid + except TypeError: + fid = 'fid=%d' % (fid) while 1: - code, text, data = self.execute('MYLISTADD s=%s&size=%d&ed2k=%s&state=%d&viewed=%d&source=%s&storage=%s&other=%s' % (self.session, size, ed2k, state, viewed and 1 or 0, source, storage, other)) + code, text, data = self.execute('MYLISTADD s=%s&%s&state=%d&viewed=%d&source=%s&storage=%s&other=%s' % (self.session, fid, states[state], viewed and 1 or 0, source, storage, other), retry) if code in [210, 310]: return - elif code in [501, 506]: - self.auth() elif code == 320: raise AniDBUnknownFile() + elif code in [501, 506]: + self.auth() else: raise AniDBReplyError(code, text) -- cgit v1.2.3