~pyshareteam/pyshare/0.6

« back to all changes in this revision

Viewing changes to plugins/Imageshack_us.py

  • Committer: Sebastian Kacprzak
  • Date: 2011-02-06 15:32:30 UTC
  • Revision ID: naicik@gmail.com-20110206153230-lh0tnr4dtmwmdjud
make uploading with password from Imageshack_us work

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/bin/env python
2
2
# -*- coding: utf-8 -*-
3
3
 
4
 
#    Copyright (C) <2009>  <Sebastian Kacprzak> <naicik |at| gmail |dot| com>
5
 
#    Partial copyright <Balazs Nagy> <nxbalazs |at| gmail |dot| com> (few lines from his drop2imageshack plasma)
 
4
#    Copyright (C) <2009,2011>  <Sebastian Kacprzak> <naicik |at| gmail |dot| com>
6
5
 
7
6
#    This program is free software: you can redistribute it and/or modify
8
7
#    it under the terms of the GNU General Public License as published by
17
16
#    You should have received a copy of the GNU General Public License
18
17
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
18
 
20
 
import gettext
21
 
gettext.bindtextdomain('sendToImageshack', '.')
22
 
gettext.textdomain('sendToImageshack')
23
 
_ = gettext.gettext
24
 
 
25
 
 
26
 
import pycurl
27
 
from threading import Thread
28
 
#import os
 
19
 
 
20
from AbstractPycurlPlugin import AbstractPycurlPlugin
 
21
from pycurl import FORM_FILE
29
22
#from helpers.gnomeHelper import getMimeTypes
30
23
from StringIO import StringIO
31
 
from threading import BoundedSemaphore
32
24
from xml.dom import minidom
33
25
from libs.uploadHelper import createLinks
34
26
from libs.cliHelper import printLink, printProgressToCLI
35
 
#from DB import DB
36
 
#db=DB()
37
 
from plugins.libs.pycurlHelper import getPycurlProxyAuthenticationType
38
 
from Settings import Settings
39
 
set = Settings()
40
 
 
41
 
 
42
 
acceptedFiletypes = ["jpg", "bmp", "gif", "png", "tif"]
43
 
acceptImageExtensions = acceptedFiletypes #depracated, use acceptedFiletypes instead
44
 
hosting_name="Imageshack"
45
 
def getAcceptedImageTypes(): #depracated, use acceptedFiletypes instead
46
 
    return acceptImageExtensions
47
 
 
48
 
def correctExtension(file): #depracated
49
 
    """checks if given string have a allowed extension"""
50
 
    #TODO: switch to checking mime types
51
 
    return file.split('.')[-1].lower() in acceptImageExtensions
52
 
 
53
 
def getName():
54
 
    return hosting_name
55
 
 
56
 
class SendToImageshack():
 
27
 
 
28
class Imageshack_us(AbstractPycurlPlugin):
 
29
    NAME = "Imageshack"
 
30
    acceptedFiletypes = ["jpg", "bmp", "gif", "png", "tif"]
 
31
    canUsePassword = True
57
32
 
58
33
    def __init__(self, fileNumber, progressCallbackFunction):
59
34
        self.fileNumber = fileNumber
60
35
        self.progressCallbackFunction = progressCallbackFunction
61
36
 
62
 
    def parseXML(self, xml):
 
37
    def parseResponse(self, xml, fileName = None):
63
38
        """parse given xml
64
39
        returns dictionary with keys: IM, Forum, Alt Forum, HTML, Direct, Forum Thumb, Alt Forum Thumb, HTML Thumb, Twitter Link"""
65
40
        xmldoc = minidom.parse(StringIO(xml))
71
46
        if thumbExists == "no":
72
47
            thumbLink = imageLink # thumb was not generated, use image as a thumb
73
48
        links = createLinks(adLink, None, imageLink,thumbLink)
74
 
        return links, [imageLink, thumbLink, adLink]
 
49
        return links#, [imageLink, thumbLink, adLink]
75
50
 
76
51
    def progress(self, download_t, download_d, upload_t, upload_d):
77
52
        """passes self.fileNumber and arguments to self.progressCallbackFunction"""
78
53
        self.progressCallbackFunction(self.fileNumber, download_t, download_d, upload_t, upload_d)
79
54
 
80
 
    def upload(self, file, semaphore, callbackFunction):
81
 
        """can throw errors"""
82
 
        if not correctExtension(file): # usually this check is not needed, but it can help later in other script
83
 
            raise Exception(_("Invalid file extension\nYou can upload only ") + str(acceptImageExtensions), _("Invalid file extension"))
84
 
 
 
55
    def __changePngExtensionIfNeeded(self, file):
85
56
        #workaround for imageshack failing to accept png https://bugs.launchpad.net/pyshare/+bug/587255
86
57
        #copies png files to temporary file with jpg extension
87
58
        #imports are embed to make it easier to delete workaround when no longer needed
91
62
            from shutil import copyfile
92
63
            copyfile(file, tempName)
93
64
            file = tempName
94
 
 
95
 
        curl = pycurl.Curl()
96
 
 
97
 
        curl.setopt(pycurl.URL, "http://www.imageshack.us/index.php")
98
 
        #curl.setopt(pycurl.HTTPHEADER, ["Except:"])
99
 
        if(set.getUseProxy()):
100
 
            curl.setopt(pycurl.PROXY,set.getProxyName())
101
 
            curl.setopt(pycurl.PROXYPORT, set.getProxyPort())
102
 
            credentials = set.getProxyCredentials()
103
 
            if credentials:
104
 
                userNameAndPassword = credentials[0] + ":" + credentials[1]
105
 
                curl.setopt(pycurl.PROXYUSERPWD,userNameAndPassword)
106
 
                del userNameAndPassword
107
 
                del credentials
108
 
            curl.setopt(pycurl.PROXYAUTH,getPycurlProxyAuthenticationType())
109
 
        curl.setopt(pycurl.POST, 1)
110
 
        curl.setopt(pycurl.HTTPPOST, [('fileupload', (pycurl.FORM_FILE, file)), ('xml', 'yes')])
111
 
 
112
 
        buf = StringIO()
113
 
        curl.setopt(pycurl.WRITEFUNCTION, buf.write)
114
 
        curl.setopt(curl.NOPROGRESS, 0)
115
 
        curl.setopt(curl.PROGRESSFUNCTION, self.progress)
116
 
 
117
 
        semaphore.acquire()
118
 
        try:
119
 
            result = curl.perform()
120
 
        except pycurl.error:
121
 
            semaphore.release()
122
 
            raise Exception(file)
123
 
        semaphore.release()
124
 
        response = buf.getvalue().strip()
125
 
        try:
126
 
            links, basicLinks = self.parseXML(response) # sometimes there are leading witespace in stream and minidom don't like them
127
 
        except IndexError:
128
 
             raise Exception("error uploading file: " + str(file) + "\n" + response)
129
 
#        db.addImage("Imageshack",basicLinks[0], basicLinks[1], os.path.basename(file), os.path.getsize(file),file.split('.')[-1].lower(), getMimeTypes(file))
130
 
        callbackFunction(links,self.fileNumber,file)
131
 
        
132
 
 
 
65
        return file
 
66
    
 
67
    def upload(self, file, callbackFunction, username, password):
 
68
        """Uploads file, and passed links to callbackFunction.
 
69
        Optionaly this method may call self.progress to inform about upload status"""
 
70
 
 
71
        file = self.__changePngExtensionIfNeeded(file)
 
72
        post =  [('fileupload', (FORM_FILE, file)),  ('xml', 'yes')]
 
73
        if username:
 
74
            post.append(('a_username', username))
 
75
            post.append(('a_password', password))
 
76
        self.uploadUsingPycurlPost(file, callbackFunction,
 
77
            "http://www.imageshack.us/index.php",
 
78
            #"http://www.imageshack.us/upload_api.php", #returns more info, that we don't need
 
79
            post)
 
80
 
 
81
 
 
82
 
 
83
#used only if __name__ == "__main__"
 
84
from threading import Thread
 
85
from threading import BoundedSemaphore
133
86
def uploadFile(file, resultCallbackFunction=printLink, progressCallbackFunction=printProgressToCLI, fileNumber = 0, semaphore = BoundedSemaphore(2), username="", password=""):
134
 
    sti = SendToImageshack(fileNumber, progressCallbackFunction)
 
87
    sti = Imageshack_us(fileNumber, progressCallbackFunction)
135
88
    sti.upload(file, semaphore, resultCallbackFunction)
136
89
 
 
90
#used only if __name__ == "__main__"
137
91
def uploadFiles(files, resultCallbackFunction=printLink, progressCallbackFunction=printProgressToCLI, fileNumber = 0, semaphore = BoundedSemaphore(2)):
138
92
    """uploads given files in threads
139
93
    This function is non blocking, you should give a callback function as parameter if you want to know when it ended or what is the progress
140
94
    Error will be thrown if upload was unsuccessful"""
141
95
    threadList = []
142
96
    for file in files:
143
 
        sti = SendToImageshack(fileNumber, progressCallbackFunction)
 
97
        sti = Imageshack_us(fileNumber, progressCallbackFunction)
144
98
        fileNumber += 1
145
99
        t = Thread(None, sti.upload, None,(file, semaphore, resultCallbackFunction))
146
100
        t.start()
155
109
        threadList = uploadFiles(args)
156
110
        for thread in threadList:
157
111
            thread.join() # wait for all threads to end
158