changeset 4a3d1e985d27 in /home/hg/repos/gajim-plugins
author: Jefry Lagrange <jefry.reyes(a)gmail.com>
branches:
details:gajim-plugins?cmd=changeset;node=4a3d1e985d27
description: fix on_request
diffstat:
file_sharing/database.py | 31 ++++++++-----
file_sharing/fshare.py | 2 +-
file_sharing/fshare_protocol.py | 89 ++++++++++++++++++++++++++++---------
file_sharing/tests/TestProtocol.py | 60 ++++++++++++++++++++++--
4 files changed, 139 insertions(+), 43 deletions(-)
diffs (truncated from 326 to 300 lines):
diff -r 0b93039de291 -r 4a3d1e985d27 file_sharing/database.py
--- a/file_sharing/database.py Sat Aug 31 11:32:26 2013 +0400
+++ b/file_sharing/database.py Sat Aug 31 20:52:19 2013 -0400
@@ -1,12 +1,19 @@
import sqlite3
-from common import gajim
import sys
import os
+'''
+TODO:
+ 1-) Modify the database class to use models instead of method arguments
+ 2-) Normalize the database. Don't save dirs and files in the same table
+'''
+
class FilesharingDatabase:
- def __init__(self, plugin):
- self.plugin = plugin
- path_l = os.path.split(plugin.config.FILE_PATH)
+
+ def __init__(self, FILE_PATH=None):
+ if not FILE_PATH:
+ return
+ path_l = os.path.split(FILE_PATH)
path = os.path.join(path_l[0], 'shared_files.db')
db_exist = os.path.exists(path)
self.conn = sqlite3.connect(path)
@@ -31,13 +38,13 @@
self.conn.commit()
c.close()
- def get_toplevel_files(self, account, requester):
+ def get_toplevel_dirs(self, account, requester):
c = self.conn.cursor()
data = (account, requester)
c.execute("SELECT relative_path, hash_sha1, size, description, " +
"mod_date, is_dir FROM (files JOIN permissions ON" +
" files.fid=permissions.fid) WHERE account=? AND requester=?" +
- " AND relative_path NOT LIKE '%/%'", data)
+ " AND is_dir=1 AND relative_path NOT LIKE '%/%'", data)
result = c.fetchall()
c.close()
return result
@@ -88,16 +95,15 @@
else:
data = (account, requester, name)
sql = "SELECT relative_path, hash_sha1, size, description, " + \
- "mod_date, file_path FROM (files JOIN permissions ON" + \
+ "mod_date, file_path, is_dir FROM (files JOIN permissions ON" + \
" files.fid=permissions.fid) WHERE account=? AND requester=?" +\
" AND relative_path=?"
c.execute(sql, data)
result = c.fetchall()
c.close()
- if result == []:
- return None
- else:
+ if result != []:
return result[0]
+ return result
def get_files_name(self, account, requester):
result = self.get_files(account, requester)
@@ -115,7 +121,8 @@
>>> _delete_file(1)
"""
self._check_duplicate(account, requester, file_)
- requester = gajim.get_jid_without_resource(requester)
+ if requester.find('/') != -1:
+ raise Exception('The requester must be given without a resource attached')
c = self.conn.cursor()
c.execute("INSERT INTO files (file_path, " +
"relative_path, hash_sha1, size, description, mod_date, " +
@@ -138,7 +145,7 @@
data = (account, requester, file_[2])
c.execute("SELECT * FROM (files JOIN permissions ON" +
" files.fid=permissions.fid) WHERE account=? AND requester=?" +
- " AND hash_sha1=?)", data)
+ " AND hash_sha1=?", data)
result.extend(c.fetchall())
if len(result) > 0:
raise Exception('Duplicated entry')
diff -r 0b93039de291 -r 4a3d1e985d27 file_sharing/fshare.py
--- a/file_sharing/fshare.py Sat Aug 31 11:32:26 2013 +0400
+++ b/file_sharing/fshare.py Sat Aug 31 20:52:19 2013 -0400
@@ -29,7 +29,7 @@
self.config_dialog = FileSharePluginConfigDialog(self)
home_path = os.path.expanduser('~/')
self.config_default_values = {'incoming_dir': (home_path, '')}
- self.database = database.FilesharingDatabase(self)
+ self.database = database.FilesharingDatabase(self.config.FILE_PATH)
# Create one protocol handler per account
accounts = gajim.contacts.get_accounts()
for account in gajim.contacts.get_accounts():
diff -r 0b93039de291 -r 4a3d1e985d27 file_sharing/fshare_protocol.py
--- a/file_sharing/fshare_protocol.py Sat Aug 31 11:32:26 2013 +0400
+++ b/file_sharing/fshare_protocol.py Sat Aug 31 20:52:19 2013 -0400
@@ -21,6 +21,27 @@
# set our jid with resource
self.ourjid = ourjid
+
+ def convert_dbformat(self, records):
+ # Converts db output format to the one expected by the Protocol methods
+ formatted = []
+ for record in records:
+ r = {'name' : record[0]}
+ if record[-1] == 0:
+ r['type'] = 'file'
+ if record[1] != None or record[1] != '':
+ r['hash'] = record[1]
+ if record[2] != None or record[2] != '':
+ r['size'] = record[2]
+ if record[3] != None or record[3] != '':
+ r['desc'] = record[3]
+ if record[4] != None or record[4] != '':
+ r['date'] = record[4]
+ else:
+ r['type'] = 'directory'
+ formatted.append(r)
+ return formatted
+
def request(self, contact, stanzaID, path=None):
iq = nbxmpp.Iq(typ='get', to=contact, frm=self.ourjid)
iq.setID(stanzaID)
@@ -66,7 +87,7 @@
raise Exception("Unexpected Type")
return iq
-class ProtocolDispatcher():
+class ProtocolDispatcher(Protocol):
'''
Sends and receives stanzas
'''
@@ -77,7 +98,8 @@
self.plugin = plugin
self.conn = gajim.connections[self.account]
# get our jid with resource
- self.ourjid = gajim.get_jid_from_account(self.account)
+ ourjid = gajim.get_jid_from_account(self.account)
+ Protocol.__init__(self, ourjid)
self.fsw = None
@@ -96,31 +118,48 @@
# TODO: reply with malformed stanza error
pass
+
+ def on_toplevel_request(self, stanza, jid):
+ roots = self.plugin.database.get_toplevel_dirs(self.account, jid)
+ items = []
+ for root in roots:
+ items.append({'type' : 'directory',
+ 'name' : root[0]
+ })
+ return self.offer(stanza.getID(), jid, None, items)
+
+ def on_dir_request(self, stanza, fjid, jid, dir_):
+ result = self.plugin.database.get_files_from_dir(self.account, jid, dir_)
+ result = self.convert_dbformat(result)
+ return self.offer(stanza.getID(), fjid, dir_, result)
+
def on_request(self, stanza, fjid):
- node = stanza.getQuery().getAttr('node')
- jid = gajim.get_jid_without_resource(fjid)
- result = self.plugin.database.get_file(self.account, jid, None, node)
- return
-
-
+ jid = get_jid_without_resource(fjid)
if stanza.getTag('error'):
# TODO: better handle this
return -1
- jid = gajim.get_jid_without_resource(fjid)
- req = stanza.getTag('match').getTag('request')
- if req.getTag('directory') and not \
- req.getTag('directory').getChildren():
- # We just received a toplevel directory request
- files = self.plugin.database.get_toplevel_files(self.account, jid)
- response = self.offer(stanza.getID(), fjid, files)
- self.conn.connection.send(response)
- return response
- elif req.getTag('directory') and req.getTag('directory').getTag('name'):
- dir_ = req.getTag('directory').getTag('name').getData()[1:]
- files = self.plugin.database.get_files_from_dir(self.account, jid, dir_)
- response = self.offer(stanza.getID(), fjid, files)
- self.conn.connection.send(response)
- return response
+ node = stanza.getQuery().getAttr('node')
+ if node is None:
+ return self.on_toplevel_request(stanza, jid)
+ result = self.plugin.database.get_file(self.account, jid, None, node)
+ if result == []:
+ return self.offer(stanza.getID(), fjid, node, result)
+ if result[-1] == 1:
+ # The peer asked for the content of a dir
+ reply = self.on_dir_request(self, stanza, fjid)
+ else:
+ # The peer asked for more information on a file
+ # TODO: Refactor, make method to convert db format to expect file
+ # format
+ file_ = [{'type' : 'file',
+ 'name' : result[0].split('/')[-1],
+ 'hash' : result[1],
+ 'size' : result[2],
+ 'desc' : result[3],
+ 'date' : result[4],
+ }]
+ reply = self.offer(stanza.getID(), fjid, node, file_)
+ return reply
def on_offer(self, stanza, fjid):
offered = []
@@ -140,6 +179,10 @@
return offered
+
+def get_jid_without_resource(jid):
+ return jid.split('/')[0]
+
def get_files_info(stanza):
# Crawls the stanza in search for file and dir structure.
files = []
diff -r 0b93039de291 -r 4a3d1e985d27 file_sharing/tests/TestProtocol.py
--- a/file_sharing/tests/TestProtocol.py Sat Aug 31 11:32:26 2013 +0400
+++ b/file_sharing/tests/TestProtocol.py Sat Aug 31 20:52:19 2013 -0400
@@ -22,6 +22,15 @@
self.assertEqual(iq.getQuery().getNamespace(), fshare_protocol.NS_FILE_SHARING)
self.assertEqual(iq.getQuery().getAttr('node'), 'documents/test2.txt')
+ def test_convert_dbformat(self):
+ file_ = [(u'relative_path', u'hash', 999, u'description',
+ u'date', u'file_path', 0)]
+ formatted = self.protocol.convert_dbformat(file_)
+ self.assertNotEqual(len(formatted), 0)
+ for item in formatted:
+ self.assertEqual(type(item), type({}))
+ self.assertEqual(formatted[0]['type'], 'file')
+
def test_buildFileNode(self):
file_info = {'name' : 'test2.text',
'desc' : 'test',
@@ -58,18 +67,33 @@
# Mock modules
-fshare_protocol.gajim = Mock()
+gajim = Mock()
+attr = {'get_jid_from_account.return_value': 'test(a)gajim.org/test'}
+gajim.configure_mock(**attr)
+fshare_protocol.gajim = gajim
fshare_protocol.helpers = Mock()
class TestProtocolDispatcher(unittest.TestCase):
def setUp(self):
- self.account = 'test(a)gajim.org/test'
+ self.account = 'test(a)gajim.org'
self.protocol = fshare_protocol.Protocol(self.account)
testc = {self.account : Mock()}
fshare_protocol.gajim.connections = testc
+ database = Mock()
+ top_dirs = [(u'relative_path1', None, None, None, None, 1),
+ (u'relative_path2', None, None, None, None, 1)]
+ file_ = (u'file1', u'hash', 999, u'description',
+ u'date', u'file_path', 0)
+ attr = {'get_toplevel_dirs.return_value': top_dirs,
+ 'get_file.return_value': file_,
+ 'get_files_from_dir.return_value' : [file_, top_dirs[0]]
+ }
+ database.configure_mock(**attr)
+ plugin = Mock()
+ plugin.database = database
self.dispatcher = fshare_protocol.ProtocolDispatcher(
- self.account, Mock())
+ self.account, plugin)
def test_handler(self):
iq = self.protocol.request('peer(a)gajim.org/test', '1234',
@@ -96,18 +120,40 @@
offered_files = self.dispatcher.on_offer(iq, 'peer(a)gajim.org/test')
self.assertEqual(len(offered_files), 2)
-
- def test_on_request(self):
+ def test_on_dir_request(self):
iq = self.protocol.request('peer(a)gajim.org/test', '1234',
'documents')
- response = self.dispatcher.on_request(iq, 'peer(a)gajim.org/test')
+ response = self.dispatcher.on_dir_request(iq, 'peer(a)gajim.org/test',
+ 'peer(a)gajim.org', 'documents')
self.assertEqual(response.getType(), 'result')
self.assertNotEqual(response.getID(), None)
self.assertEqual(response.getQuery().getName(), 'query')
self.assertEqual(response.getQuery().getNamespace(), fshare_protocol.NS_FILE_SHARING)
self.assertEqual(response.getQuery().getAttr('node'), 'documents')
node = response.getQuery()
- self.assertEqual(len(node.getChildren()), 0)