diff options
| author | zyp <zyp@localhost> | 2006-05-17 16:18:20 +0200 | 
|---|---|---|
| committer | zyp <zyp@localhost> | 2006-05-17 16:18:20 +0200 | 
| commit | 5e354503c2e7af39ab12e530c37e2794bc9494a9 (patch) | |
| tree | 9863db0f4ccc77b54834efa155c95e81b5ca5ebb | |
| parent | efbe12547b2250cebd08ad25b6145a902a7b0849 (diff) | |
[project @ zyp-20060517141820-307896d115926051]
[project @ 38]
Added support for identifying files.
| -rw-r--r-- | anidb.py | 36 | ||||
| -rw-r--r-- | pyanidb/__init__.py | 96 | 
2 files changed, 94 insertions, 38 deletions
| @@ -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) | 
