annotate frontends/src/jp/cmd_file.py @ 853:c2f6ada7858f

core (sqlite): automatic database update: - new Updater class check database consistency (by calculating a hash on the .schema), and updates base if necessary - database now has a version (1 for current, 0 will be for 0.3's database), for each change this version will be increased - creation statements and update statements are in the form of dict of dict with tuples. There is a help text at the top of the module to explain how it works - if we are on a development version, the updater try to update the database automaticaly (without deleting table or columns). The Updater.generateUpdateData method can be used to ease the creation of update data (i.e. the dictionary at the top, see the one for the key 1 for an example). - if there is an inconsistency, an exception is raised, and a message indicate the SQL statements that should fix the situation. - well... this is rather complicated, a KISS method would maybe have been better. The future will say if we need to simplify it :-/ - new DatabaseError exception
author Goffi <goffi@goffi.org>
date Sun, 23 Feb 2014 23:30:32 +0100
parents 300b4de701a6
children 069ad98b360d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
815
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
1 #! /usr/bin/python
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
2 # -*- coding: utf-8 -*-
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
3
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
4 # jp: a SAT command line tool
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
5 # Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Jérôme Poisson (goffi@goffi.org)
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
6
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
7 # This program is free software: you can redistribute it and/or modify
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
10 # (at your option) any later version.
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
11
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
12 # This program is distributed in the hope that it will be useful,
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
15 # GNU Affero General Public License for more details.
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
16
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
f8d534ed1d1e jp: added missing license headers
Goffi <goffi@goffi.org>
parents: 814
diff changeset
19
814
59c7bc51c323 jp: refactoring using ArgParse
Dal <kedals0@gmail.com>
parents: 811
diff changeset
20 from logging import debug, info, error, warning
0
goffi@necton2
parents:
diff changeset
21
814
59c7bc51c323 jp: refactoring using ArgParse
Dal <kedals0@gmail.com>
parents: 811
diff changeset
22 import base
59c7bc51c323 jp: refactoring using ArgParse
Dal <kedals0@gmail.com>
parents: 811
diff changeset
23 import sys
59c7bc51c323 jp: refactoring using ArgParse
Dal <kedals0@gmail.com>
parents: 811
diff changeset
24 import os
59c7bc51c323 jp: refactoring using ArgParse
Dal <kedals0@gmail.com>
parents: 811
diff changeset
25 import os.path
59c7bc51c323 jp: refactoring using ArgParse
Dal <kedals0@gmail.com>
parents: 811
diff changeset
26 import tarfile
771
bfabeedbf32e core: i18n refactoring:
Goffi <goffi@goffi.org>
parents: 721
diff changeset
27 from sat.core.i18n import _
402
f03688bdb858 jp: use with statement to open fifo
Goffi <goffi@goffi.org>
parents: 401
diff changeset
28
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
29 __commands__ = ["File"]
0
goffi@necton2
parents:
diff changeset
30
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
31 class Send(base.CommandBase):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
32 def __init__(self, host):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
33 super(Send, self).__init__(host, 'send', use_progress=True, help=_('Send a file to a contact'))
0
goffi@necton2
parents:
diff changeset
34
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
35 def add_parser_options(self):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
36 self.parser.add_argument("files", type=str, nargs = '+', help=_("A list of file"))
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
37 self.parser.add_argument("jid", type=base.unicode_decoder, help=_("The destination jid"))
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
38 self.parser.add_argument("-b", "--bz2", action="store_true", help=_("Make a bzip2 tarball"))
0
goffi@necton2
parents:
diff changeset
39
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
40 def connected(self):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
41 """Send files to jabber contact"""
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
42 self.need_loop=True
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
43 super(Send, self).connected()
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
44 self.send_files()
401
b2caa2615c4c jp roster name manegement + Pipe transfer
Goffi <goffi@goffi.org>
parents: 393
diff changeset
45
0
goffi@necton2
parents:
diff changeset
46 def send_files(self):
goffi@necton2
parents:
diff changeset
47
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
48 for file_ in self.args.files:
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
49 if not os.path.exists(file_):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
50 error (_(u"file [%s] doesn't exist !") % file_)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
51 self.host.quit(1)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
52 if not self.args.bz2 and os.path.isdir(file_):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
53 error (_("[%s] is a dir ! Please send files inside or use compression") % file_)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
54 self.host.quit(1)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
55
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
56 full_dest_jid = self.host.get_full_jid(self.args.jid)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
57
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
58 if self.args.bz2:
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
59 tmpfile = (os.path.basename(self.args.files[0]) or os.path.basename(os.path.dirname(self.args.files[0])) ) + '.tar.bz2' #FIXME: tmp, need an algorithm to find a good name/path
0
goffi@necton2
parents:
diff changeset
60 if os.path.exists(tmpfile):
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
61 error (_("tmp file_ (%s) already exists ! Please remove it"), tmpfile)
0
goffi@necton2
parents:
diff changeset
62 exit(1)
70
Goffi <goffi@goffi.org>
parents: 57
diff changeset
63 warning(_("bz2 is an experimental option at an early dev stage, use with caution"))
0
goffi@necton2
parents:
diff changeset
64 #FIXME: check free space, writting perm, tmp dir, filename (watch for OS used)
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
65 print _(u"Starting compression, please wait...")
0
goffi@necton2
parents:
diff changeset
66 sys.stdout.flush()
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
67 bz2 = tarfile.open(tmpfile, "w:bz2")
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
68 for file_ in self.args.files:
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
69 print _(u"Adding %s") % file_
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
70 bz2.add(file_)
0
goffi@necton2
parents:
diff changeset
71 bz2.close()
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
72 print _(u"Done !")
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
73 path = os.path.abspath(tmpfile)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
74 self.progress_id = self.host.bridge.sendFile(full_dest_jid, path, {}, self.profile)
0
goffi@necton2
parents:
diff changeset
75 else:
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
76 for file_ in self.args.files:
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
77 path = os.path.abspath(file_)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
78 self.progress_id = self.host.bridge.sendFile(full_dest_jid, path, {}, self.profile) #FIXME: show progress only for last progress_id
587
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
79
952322b1d490 Remove trailing whitespaces.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents: 572
diff changeset
80
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
81 class Receive(base.CommandAnswering):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
82 confirm_type = "FILE_TRANSFER"
0
goffi@necton2
parents:
diff changeset
83
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
84 def __init__(self, host):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
85 super(Receive, self).__init__(host, 'recv', use_progress=True, help=_('Wait for a file to be sent by a contact'))
0
goffi@necton2
parents:
diff changeset
86
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
87 @property
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
88 def dest_jids(self):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
89 return self.args.jids
393
393b35aa86d2 jp: added --connect option
Goffi <goffi@goffi.org>
parents: 391
diff changeset
90
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
91 def add_parser_options(self):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
92 self.parser.add_argument("jids", type=base.unicode_decoder, nargs="*", help=_('Jids accepted (none means "accept everything")'))
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
93 self.parser.add_argument("-m", "--multiple", action="store_true", help=_("Accept multiple files (you'll have to stop manually)"))
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
94 self.parser.add_argument("-f", "--force", action="store_true", help=_("Force overwritting of existing files"))
0
goffi@necton2
parents:
diff changeset
95
goffi@necton2
parents:
diff changeset
96
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
97 def ask(self, data, confirm_id):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
98 answer_data = {}
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
99 answer_data["dest_path"] = os.path.join(os.getcwd(), data['filename'])
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
100
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
101 if self.args.force or not os.path.exists(answer_data["dest_path"]):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
102 self.host.bridge.confirmationAnswer(confirm_id, True, answer_data, self.profile)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
103 info(_("Accepted file [%(filename)s] from %(sender)s") % {'filename':data['filename'], 'sender':data['from']})
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
104 self.progress_id = confirm_id
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
105 else:
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
106 self.host.bridge.confirmationAnswer(confirm_id, False, answer_data, self.profile)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
107 warning(_("Refused file [%(filename)s] from %(sender)s: a file with the same name already exist") % {'filename':data['filename'], 'sender':data['from']})
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
108 if not self.args.multiple:
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
109 self.host.quit()
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
110
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
111 if not self.args.multiple and not self.args.progress:
814
59c7bc51c323 jp: refactoring using ArgParse
Dal <kedals0@gmail.com>
parents: 811
diff changeset
112 #we just accept one file
817
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
113 self.host.quit()
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
114
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
115 def run(self):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
116 super(Receive, self).run()
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
117 if self.args.multiple:
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
118 self.host.quit_on_progress_end = False
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
119
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
120
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
121 class File(base.CommandBase):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
122 subcommands = (Send, Receive)
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
123
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
124 def __init__(self, host):
c39117d00f35 jp: refactoring:
Goffi <goffi@goffi.org>
parents: 815
diff changeset
125 super(File, self).__init__(host, 'file', use_profile=False, help=_('File sending/receiving'))