~lookit/lookit/mirror

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
import os
import sys
import gtk
import ftplib
import pynotify
import shutil
import socket
import tempfile
import time
import urllib
import urlparse

PROTO_LIST = ['None']

try:
	import ftplib
	PROTO_LIST.append('FTP')
except ImportError:
	print 'FTP support not found'

try:
	import paramiko
	PROTO_LIST.append('SSH')
except ImportError:
	print 'SFTP support not found'

try:
	import ubuntuone
	import ubuntuone.storageprotocol
	# PROTO_LIST.append('Ubuntu One') # Not yet supported
except ImportError:
	print 'Ubuntu One support not found'

try:
    import imgur
    PROTO_LIST.append('Imgur')
except ImportError:
    print 'Imgur support not available'

try:
	import pycurl
	import re
	PROTO_LIST.append('Omploader')
	PROTO_LIST.append('HTTP')
except ImportError:
	print 'Omploader support not available'
	print 'HTTP support not available'

try:
    import cloud
    if cloud.POSTER and cloud.ORDERED_DICT:
        PROTO_LIST.append('CloudApp')
    else:
        print 'CloudApp support not available'
except ImportError:
    print 'CloudApp support not available'

import liblookit
import lookitconfig

class OmploaderUploader:
	def __init__(self):
		self.response = ''
		self.mapping = {}

	def curl_response(self, buf):
		self.response = self.response + buf

	def upload(self, image):
		c = pycurl.Curl()
		values = [	('file1', (c.FORM_FILE, image))]
		c.setopt(c.URL, 'http://ompldr.org/upload')
		c.setopt(c.HTTPPOST, values)
		c.setopt(c.WRITEFUNCTION, self.curl_response)

		c.perform()
		c.close()

		m = re.findall("v\w+", self.response)
		self.mapping['original_image'] = "http://ompldr.org/%s" % m[2]


class HTTPUploader:
	def __init__(self):
		self.response = ''

	def curl_response(self, buf):
		self.response = self.response + buf

	def upload(self, image, url):
		c = pycurl.Curl()
		values = [	('file', (c.FORM_FILE, image))]
		c.setopt(c.URL, url)
		c.setopt(c.HTTPPOST, values)
		c.setopt(c.WRITEFUNCTION, self.curl_response)

		try:
			c.perform()
		except pycurl.error:
			c.close()
			return False, "There was an error during HTTP upload."

		c.close()

		return True, self.response

def get_proto_list():
	return PROTO_LIST

def upload_file_ftp(f, hostname, port, username, password, directory, url):
	i = open(f, 'rb')

	try:
		ftp = ftplib.FTP()
		ftp.connect(hostname, port)
		ftp.login(username, password)
		ftp.cwd(directory)
		ftp.storbinary('STOR ' + os.path.basename(f), i)
		ftp.quit()
	except Exception as error:
		return False, 'Error occured during FTP upload'

	i.close()

	return True, None

def upload_file_http(f, url):
	i = HTTPUploader()

	status, data = i.upload(f, url)

	if status:
		obj = {}
		obj['original_image'] = data;

		return True, obj
	else:
		return False, data

def upload_file_sftp(f, hostname, port, username, password, ssh_key_file, directory, url):
    try:
        # Debug info.
        #paramiko.util.log_to_file('paramiko.log')

        # Paramiko needs 'None' for these two, probably a bad place to put them
        # but I'm lazy.
        if password == '':
            password = None
        if ssh_key_file == '':
            ssh_key_file = None

        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(hostname, port, username, password, key_filename=ssh_key_file)
        sftp = client.open_sftp()
        sftp.chdir(directory)
        sftp.put(f, os.path.basename(f))
    except socket.gaierror:
        return False, 'Name or service not known'
    except paramiko.AuthenticationException:
        return False, 'Authentication failed'
    except IOError:
        return False, 'Destination directory does not exist'
    return True, None

def upload_file_omploader(f):
	if not 'Omploader' in PROTO_LIST:
		print 'Error: Omploader not supported'
	i = OmploaderUploader()
	i.upload(f)
	if not 'error_msg' in i.mapping:
		return True, i.mapping
	else:
		return False, i.mapping.get('error_msg')

def upload_file_imgur(f):
	if not 'Imgur' in PROTO_LIST:
		print 'Error: Imgur not supported'
	i = imgur.ImgurUploader()
	i.upload(f)
	if not 'error_msg' in i.mapping:
		return True, i.mapping
	else:
		return False, i.mapping.get('error_msg')

def upload_file_cloud(f, username, password):
    if not 'CloudApp' in PROTO_LIST:
        print 'Error: CloudApp not supported'
    try:
        mycloud = cloud.Cloud()
        mycloud.auth(username, password)
        result = mycloud.upload_file(f)
        data = {'original_image': result['url']}
        return True, data
    except cloud.CloudException as e:
        return False, e.message

def upload_pixbuf(pb):
    if pb is not None:
        ftmp = tempfile.NamedTemporaryFile(suffix='.png', prefix='', delete=False)
        pb.save_to_callback(ftmp.write, 'png')
        ftmp.flush()
        ftmp.close()
        return upload_file(ftmp.name)

def upload_file(image, existing_file=False):
    config = lookitconfig.LookitConfig()

    proto = config.get('Upload', 'type')
    # Temporary disable upload
    if not config.getboolean('Upload', 'enableupload'):
        proto = 'None'

    if proto == 'None':
        success = True
        data = False
    elif proto == 'SSH':
        success, data = upload_file_sftp(image,
                    config.get('Upload', 'hostname'),
                    int(config.get('Upload', 'port')),
                    config.get('Upload', 'username'),
                    config.get('Upload', 'password'),
                    config.get('Upload', 'ssh_key_file'),
                    config.get('Upload', 'directory'),
                    config.get('Upload', 'url'),
                    )
    elif proto == 'HTTP':
	success, data = upload_file_http(image, config.get('Upload', 'URL'))
    elif proto == 'FTP':
        success, data = upload_file_ftp(image,
                    config.get('Upload', 'hostname'),
                    int(config.get('Upload', 'port')),
                    config.get('Upload', 'username'),
                    config.get('Upload', 'password'),
                    config.get('Upload', 'directory'),
                    config.get('Upload', 'url'),
                    )
    elif proto == 'Omploader':
        success, data = upload_file_omploader(image)
        try:
            f = open(liblookit.LOG_FILE, 'ab')
            f.write(time.ctime() + ' Uploaded screenshot to Omploader: ' + data['original_image'] + '\n')
        except IOError, e:
            pass
        finally:
            f.close()
    elif proto == 'Imgur':
        success, data = upload_file_imgur(image)
        # Backwards compatibility
        data['original_image'] = data['link']
        try:
            f = open(liblookit.LOG_FILE, 'ab')
            f.write(time.ctime() + ' Uploaded screenshot to Imgur: ' + data['original_image'] + '\n')
        except IOError, e:
            pass
        finally:
            f.close()
    elif proto == 'CloudApp':
        success, data = upload_file_cloud(image,
                    config.get('Upload', 'username'),
                    config.get('Upload', 'password'))
    else:
        success = False
        data = "Error: no such protocol: {0}".format(proto)

    if not success:
        liblookit.show_notification('Lookit', 'Error: ' + data)
        return

    if data:
        url = data['original_image']
    else:
        url = urlparse.urljoin(config.get('Upload', 'url'),
            os.path.basename(image))

    if config.getboolean('General', 'shortenurl') and proto != None:
        url = urllib.urlopen('http://is.gd/api.php?longurl={0}'
                        .format(url)).readline()
    if not existing_file:
        if config.getboolean('General', 'trash'):
            os.remove(os.path.abspath(image))
        else:
            try:
                timestamp = time.strftime('%Y-%m-%d_%H-%M-%S')
                filename = timestamp + '.png'
                destination = os.path.join(config.get('General', 'savedir'), filename)
                i = 0
                while os.path.exists(destination):
                    filename = timestamp + '_' + str(i) + '.png'
                    destination = os.path.join(config.get('General', 'savedir'), filename)
                    i += 1
                shutil.move(image, destination)
                image = destination
            except IOError:
                print 'Error moving file'

    clipboard = gtk.clipboard_get()
    clipboard.set_text(url)
    clipboard.store()

    if proto == 'None':
        if config.getboolean('General', 'trash'):
            liblookit.show_notification('Lookit', 'Error: No upload type selected')
        else:
            liblookit.show_notification('Lookit', 'Image saved: ' + image)
            return image
    else:
        liblookit.show_notification('Lookit', 'Upload complete: ' + url)
        return url