Democratic Underground Latest Greatest Lobby Journals Search Options Help Login
Google

I've made a Python script to upload pictures to Photobucket

Printer-friendly format Printer-friendly format
Printer-friendly format Email this thread to a friend
Printer-friendly format Bookmark this thread
Home » Discuss » DU Groups » Computers & Internet » Open Source and Free Software Group Donate to DU
 
Syrinx Donating Member (1000+ posts) Send PM | Profile | Ignore Fri Aug-05-05 02:19 AM
Original message
I've made a Python script to upload pictures to Photobucket
Edited on Fri Aug-05-05 02:21 AM by Syrinx
If anyone would find such a thing useful, I'll be glad to share it.

I'm using it to update my nifty sig here via crond each midnight. ;)

It took me several hours over a couple of nights to figure out how to make it work. Finally, I realized that in a multipart HTTP POST, the boundary used is actually "--" PLUS the declared boundary. I don't know why that is, but I figure there's a good reason.

My script has no error checking really, and it doesn't understand sub-albums, as I store all my pictures in my root album. It would probably be easy to add sub-albums though.

On the upside, it's really easy to use. To upload a picture, just do:

photobucket -u foo.jpg

You can also use wildcards. To upload every jpg file in the current directory:

photobucket -u *.jpg

To delete a picture:

photobucket -d foo.jpg

(Wildcards don't work with deletions. That would have complicated matters a little, and it wasn't something I needed.)

I tried to post the script here, but the formatting got all messed up, and as we know, formatting is very important for Python.

And, yes, I did look at Photobuckets terms of service, and I didn't see anything that prohibited this type of thing.

If anyone wants it just let me know, and I'll get it to you.

Refresh | 0 Recommendations Printer Friendly | Permalink | Reply | Top
bemildred Donating Member (1000+ posts) Send PM | Profile | Ignore Fri Aug-05-05 05:11 AM
Response to Original message
1. I'll bite.
How big is it?
Can you just post it?

Printer Friendly | Permalink | Reply | Top
 
Syrinx Donating Member (1000+ posts) Send PM | Profile | Ignore Fri Aug-05-05 04:14 PM
Response to Reply #1
2. here it is; you'll probably have to massage the formatting a bit
Edited on Fri Aug-05-05 04:17 PM by Syrinx
Just fill in the three variables at the top.

EDIT: Leading spaces don't seem to take on here. But I think the intended indentations should be pretty obvious.

#!/usr/bin/env python

import urllib
import httplib
import sys
import glob
import os.path

USERNAME = ''
PASSWORD = ''
VOLUME = ''

class FileUploadRequest:

def __init__(self, uri, host, port):
self.uri = uri
self.host = host
self.port = port
self.queryString = None
self.boundary= '-----------------------------11477706891467868222366684681'
self.parts = []

def loadfile(self, filepath, fieldname, headerDict=None):
f = PrivoxyWindowOpen(filepath, 'rb')
data = f.read()
f.close()
if filepath.find('/') != -1:
filename = filepath.split('/')<-1>
else:
filename = filepath
hdr = []
hdr.append('%s' % ('--' + self.boundary))
hdr.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (fieldname, filename))
if filename.lower().endswith('jpg') or filename.lower().endswith('jpeg'):
hdr.append('Content-Type: image/jpeg')
elif filename.lower().endswith('gif'):
hdr.append('Content-Type: image/gif')
elif filename.lower().endswith('png'):
hdr.append('Content-Type: image/png')
if type(headerDict) == type({}):
for k in headerDict.keys():
hdr.append("%s: %s", (k, headerDict))
part = '%s\r\n\r\n%s' % ('\r\n'.join(hdr) , data)
self.parts.extend()

def loadfield(self, fieldname, data, headerDict=None):
hdr = []
hdr.append('%s' % ('--' + self.boundary))
hdr.append('Content-Disposition: form-data; name="%s"' % fieldname)
if type(headerDict) == type({}):
for k in headerDict.keys():
hdr.append("%s: %s", (k, headerDict))
part='%s\r\n\r\n%s' % ('\r\n'.join(hdr) , data)
self.parts.extend()

def request(self, cookie):
query = '%s\r\n%s' % ('\r\n'.join(self.parts), ('--' + self.boundary))
query += '--\r\n'
contentType = 'multipart/form-data; boundary=%s' % self.boundary
contentLength = str(len(query))
h = httplib.HTTP()
h.connect(self.host, self.port)
h.putrequest('POST', self.uri)
h.putheader('Host', 'photobucket.com')
h.putheader('User-Agent', 'Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.7.2) Gecko/20040803')
h.putheader('Accept', 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5')
h.putheader('Accept-Language', 'en-us,en;q=0.5')
h.putheader('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
h.putheader('Referer', 'http://photobucket.com/')
h.putheader('Content-Type', contentType)
h.putheader('Content-Length', contentLength)
h.putheader('Cookie', cookie)
h.putheader('Connection', 'close')
h.endheaders()
h.send(query)
rcode, rmsg, headers = h.getreply()
response = h.getfile().read()
return int(rcode)

def LoginToPhotobucket():
f = urllib.urlopen('http://photobucket.com/login.php?', \
urllib.urlencode({'action': 'login', 'login':'Login', 'username':USERNAME, 'password':PASSWORD}))
cookie = f.info().getheader('Set-Cookie') + ';'
cookie = cookie.replace(' path=/;', '')
return cookie

def UploadFileToPhotobucket(filepath, cookie):
if filepath.find('/') != -1:
filename = filepath.split('/')<-1>
else:
filename = filepath
uri = '/albums/' + VOLUME + '/' + USERNAME + '/?sc=3'
F = FileUploadRequest(uri, 'photobucket.com', 80)
F.loadfield("action" , "addpic")
F.loadfield("multi" , "")
F.loadfield("addtype" , "")
F.loadfile(filepath, "the_file[]")
F.loadfield("desc[]", "")
F.loadfield("preserve", "true")
F.request(cookie)

def DeleteFileFromPhotobucket(filename, cookie):
uri = '/albums/' + VOLUME + '/' + USERNAME + '/'
F = FileUploadRequest(uri, 'photobucket.com', 80)
F.loadfield('action' , 'deletepic')
F.loadfield('pic', filename)
F.loadfield('myurl' , 'http://img.photobucket.com/albums/' + VOLUME + '/' + USERNAME + '/' + filename)
F.request(cookie)

action = sys.argv<1>
if action == '-d':
cookie = LoginToPhotobucket()
for filename in sys.argv<2:>:
DeleteFileFromPhotobucket(filename, cookie)
elif action == '-u':
files = []
for spec in sys.argv<2:>:
for file in glob.glob(spec):
if os.path.isfile(file):
files.append(file)
cookie = LoginToPhotobucket()
for file in files:
UploadFileToPhotobucket(file, cookie)

Printer Friendly | Permalink | Reply | Top
 
bemildred Donating Member (1000+ posts) Send PM | Profile | Ignore Fri Aug-05-05 07:15 PM
Response to Reply #2
3. Yeah, spaces get eaten.
I'll see what I can do with it,
and thank you.
Printer Friendly | Permalink | Reply | Top
 
Syrinx Donating Member (1000+ posts) Send PM | Profile | Ignore Fri Aug-05-05 07:20 PM
Response to Reply #3
4. you're welcome
I hope it's useful to you.
Printer Friendly | Permalink | Reply | Top
 
Syrinx Donating Member (1000+ posts) Send PM | Profile | Ignore Sat Aug-06-05 01:57 AM
Response to Reply #3
5. maybe this'll make it easier
Replace each "#" with a space. :)

import urllib
import httplib
import sys
import glob
import os.path

USERNAME = ''
PASSWORD = ''
VOLUME = ''

class FileUploadRequest:

####def __init__(self, uri, host, port):
########self.uri = uri
########self.host = host
########self.port = port
########self.queryString = None
########self.boundary= '-----------------------------11477706891467868222366684681'
########self.parts = []

####def loadfile(self, filepath, fieldname, headerDict=None):
########f = PrivoxyWindowOpen(filepath, 'rb')
########data = f.read()
########f.close()
########if filepath.find('/') != -1:
############filename = filepath.split('/')<-1>
########else:
############filename = filepath
########hdr = []
########hdr.append('%s' % ('--' + self.boundary))
########hdr.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (fieldname, filename))
########if filename.lower().endswith('jpg') or filename.lower().endswith('jpeg'):
############hdr.append('Content-Type: image/jpeg')
########elif filename.lower().endswith('gif'):
############hdr.append('Content-Type: image/gif')
########elif filename.lower().endswith('png'):
############hdr.append('Content-Type: image/png')
########if type(headerDict) == type({}):
############for k in headerDict.keys():
################hdr.append("%s: %s", (k, headerDict))
########part = '%s\r\n\r\n%s' % ('\r\n'.join(hdr) , data)
########self.parts.extend()

####def loadfield(self, fieldname, data, headerDict=None):
########hdr = []
########hdr.append('%s' % ('--' + self.boundary))
########hdr.append('Content-Disposition: form-data; name="%s"' % fieldname)
########if type(headerDict) == type({}):
############for k in headerDict.keys():
################hdr.append("%s: %s", (k, headerDict))
########part='%s\r\n\r\n%s' % ('\r\n'.join(hdr) , data)
########self.parts.extend()

####def request(self, cookie):
########query = '%s\r\n%s' % ('\r\n'.join(self.parts), ('--' + self.boundary))
########query += '--\r\n'
########contentType = 'multipart/form-data; boundary=%s' % self.boundary
########contentLength = str(len(query))
########h = httplib.HTTP()
########h.connect(self.host, self.port)
########h.putrequest('POST', self.uri)
########h.putheader('Host', 'photobucket.com')
########h.putheader('User-Agent', 'Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.7.2) Gecko/20040803')
########h.putheader('Accept', 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5')
########h.putheader('Accept-Language', 'en-us,en;q=0.5')
########h.putheader('Accept-Charset', 'ISO-8859-1,utf-8;q=0.7,*;q=0.7')
########h.putheader('Referer', 'http://photobucket.com/')
########h.putheader('Content-Type', contentType)
########h.putheader('Content-Length', contentLength)
########h.putheader('Cookie', cookie)
########h.putheader('Connection', 'close')
########h.endheaders()
########h.send(query)
########rcode, rmsg, headers = h.getreply()
########response = h.getfile().read()
########return int(rcode)

def LoginToPhotobucket():
####f = urllib.urlopen('http://photobucket.com/login.php?', \
####urllib.urlencode({'action': 'login', 'login':'Login', 'username':USERNAME, 'password':PASSWORD}))
####cookie = f.info().getheader('Set-Cookie') + ';'
####cookie = cookie.replace(' path=/;', '')
####return cookie

def UploadFileToPhotobucket(filepath, cookie):
####if filepath.find('/') != -1:
########filename = filepath.split('/')<-1>
####else:
########filename = filepath
####uri = '/albums/' + VOLUME + '/' + USERNAME + '/?sc=3'
####F = FileUploadRequest(uri, 'photobucket.com', 80)
####F.loadfield("action" , "addpic")
####F.loadfield("multi" , "")
####F.loadfield("addtype" , "")
####F.loadfile(filepath, "the_file[]")
####F.loadfield("desc[]", "")
####F.loadfield("preserve", "true")
####F.request(cookie)

def DeleteFileFromPhotobucket(filename, cookie):
####uri = '/albums/' + VOLUME + '/' + USERNAME + '/'
####F = FileUploadRequest(uri, 'photobucket.com', 80)
####F.loadfield('action' , 'deletepic')
####F.loadfield('pic', filename)
####F.loadfield('myurl' , 'http://img.photobucket.com/albums/' + VOLUME + '/' + USERNAME + '/' + filename)
####F.request(cookie)

action = sys.argv<1>
if action == '-d':
####cookie = LoginToPhotobucket()
####for filename in sys.argv<2:>:
########DeleteFileFromPhotobucket(filename, cookie)
elif action == '-u':
####files = []
####for spec in sys.argv<2:>:
########for file in glob.glob(spec):
############if os.path.isfile(file):
################files.append(file)
####cookie = LoginToPhotobucket()
####for file in files:
########UploadFileToPhotobucket(file, cookie)

Printer Friendly | Permalink | Reply | Top
 
bemildred Donating Member (1000+ posts) Send PM | Profile | Ignore Sat Aug-06-05 08:36 AM
Response to Reply #5
6. I believe there is a posting mode for code snippets too,
Edited on Sat Aug-06-05 08:37 AM by bemildred
Text only or no HTML or something like that.

I would expect I can find an Emacs mode for Python to do the indentation for me in any case.

Regards.
Printer Friendly | Permalink | Reply | Top
 
qnr Donating Member (1000+ posts) Send PM | Profile | Ignore Sat Aug-06-05 07:58 PM
Response to Reply #6
7. It's just under the black line when you compose a message
Message format < > Check here if you want to format your message in plain text. Use for posting code snippets.


or you can go back and forth by using <pre> </pre> (with square brackets, of course).


(*
Title : v.mod
Last Mod : 12 July 2005
Author : Terry K. Ross
terry@aliboom.com
System : XDS Modula-2 (Linux)
Descrip : IRC bot commands that start with v
Usage : Not meant to be called directly
(called through Handler.mod)
License : GPL
*)
IMPLEMENTATION MODULE v;

IMPORT Handler;
IMPORT Message;
IMPORT StringParse;

PROCEDURE Version( parse : Message.Parse );
(* VERSION: Someone sent a CTCP VERSION request. *)
(* Pre: bot name, ctrlA and VERSION are all found, *)
(* Post: return version number, and where people can DL *)
(* the bot. *)
VAR
str : Message.strType;

BEGIN
str := Handler.ctrlA+"VERSION page_six 0.8 I'm a Source Mage GNU/Linux service bot, and I'm not available for download."+Handler.ctrlA;
Message.Notice(parse.nick, str);
END Version;

PROCEDURE Vote(parse : Message.Parse);
VAR
string : Message.strType;

BEGIN
string := "Vote is not yet implemented in this version N~, sorry.";
StringParse.Replace(string, "N~", parse.nick);
Message.PrintLine(parse.chan, string);
END Vote;


END v.


Printer Friendly | Permalink | Reply | Top
 
Syrinx Donating Member (1000+ posts) Send PM | Profile | Ignore Sun Aug-07-05 02:52 AM
Response to Reply #7
8. I could've sworn I clicked that
But I guess I didn't. Sorry.
Printer Friendly | Permalink | Reply | Top
 
DU AdBot (1000+ posts) Click to send private message to this author Click to view 
this author's profile Click to add 
this author to your buddy list Click to add 
this author to your Ignore list Sun Dec 22nd 2024, 09:20 AM
Response to Original message
Advertisements [?]
 Top

Home » Discuss » DU Groups » Computers & Internet » Open Source and Free Software Group Donate to DU

Powered by DCForum+ Version 1.1 Copyright 1997-2002 DCScripts.com
Software has been extensively modified by the DU administrators


Important Notices: By participating on this discussion board, visitors agree to abide by the rules outlined on our Rules page. Messages posted on the Democratic Underground Discussion Forums are the opinions of the individuals who post them, and do not necessarily represent the opinions of Democratic Underground, LLC.

Home  |  Discussion Forums  |  Journals |  Store  |  Donate

About DU  |  Contact Us  |  Privacy Policy

Got a message for Democratic Underground? Click here to send us a message.

© 2001 - 2011 Democratic Underground, LLC