summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzyp <zyp@localhost>2006-05-17 16:18:20 +0200
committerzyp <zyp@localhost>2006-05-17 16:18:20 +0200
commit5e354503c2e7af39ab12e530c37e2794bc9494a9 (patch)
tree9863db0f4ccc77b54834efa155c95e81b5ca5ebb
parentefbe12547b2250cebd08ad25b6145a902a7b0849 (diff)
[project @ zyp-20060517141820-307896d115926051]
[project @ 38] Added support for identifying files.
-rw-r--r--anidb.py36
-rw-r--r--pyanidb/__init__.py96
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)