×
Namespaces

Variants
Actions

Archived:Upload Photos to TwitPic with PySymbian

From Nokia Developer Wiki
Jump to: navigation, search

Archived.pngArchived: This article is archived because it is not considered relevant for third-party developers creating commercial solutions today. If you think this article is still relevant, let us know by adding the template {{ReviewForRemovalFromArchive|user=~~~~|write your reason here}}.

{{{width}}}
17 Jan
2010
Article Metadata
Code ExampleTested with
Devices(s): E63
Compatibility
Platform(s): S60 3rd Edition
S60 3rd Edition (initial release)
Article
Keywords: TwitPicAPI,TwitPic, api
Created: marcelcaraciolo (December, 27, 2009)
Last edited: hamishwillee (02 Jul 2012)


Contents

Introduction

This article will present a library API, that has been implemented for Symbian phones, in order to upload photos from them directly to the TwitPic Web Service. TwitPic is a website that allows users to easily post pictures to the Twitter micro-blogging and social media service. It's often used by journalists to upload and distribute pictures in real-time as an event is taking place.

With the "web nature" of the current smart-phones, it's possible to use the camera of a cellphones to take photos and upload them to the TwitPic. So you can share your pictures with all your friends in Twitter.

The next section will present a suitable Python module for accessing the TwitPic services. The module is on his first release so some bugs can be found. Please use the comments tab to describe problems.

S60TwitPic module

Twitpic API is well documented and recommended that developers read when building tools that upload photos to TwitPic. This module covers the two basic methods available in the API. The covered methods are:


  • upload: Use this method if you want only to upload a photo to Twitpic.
  • upload/Post: Use this method to upload an image to TwitPic and to send it as a status update to Twitter.


The sample code is below.

s60twitpic.py

__all__ = [ "TwitPicAPI" ]
__author__ = 'caraciol@gmail.com'
__version__ = '0.1'
 
 
import httplib, urllib
 
try:
import mimetypes
MIME_FLAG = True
except ImportError:
MIME_FLAG = False
 
def parse_xml(key,xml):
""" Simple XML parser """
key = key.lower()
for tag in xml.split("<"):
tokens = tag.split()
if tokens and tokens[0].lower().startswith(key):
return tag.split(">")[1].strip()
 
 
class TwitPicAPI(object):
""" Simple class for TwitPic uploading photos """
SERVER = 'twitpic.com'
PORT = 80
UPLOAD_URL = '/api/upload/'
UPLOAD_POST_URL = '/api/uploadAndPost'
 
def __init__(self,username,password,image=None,filedata=None,
server=SERVER,port=PORT,upload_url = UPLOAD_URL,
upload_post_url = UPLOAD_POST_URL):
""" Set default values for server links and
set user/password/imagePath or imageData for TwitPic """

 
self.server = server
self.port = port
self.username = username
self.password = password
self.filedata = filedata
self.image = image
self.upload_url = upload_url
self.upload_post_url = upload_post_url
self.connection = None
 
def encode_multipart_formdata(self,params=None):
"""Create the body and the content type of the POST """
BOUNDARY= '-------tHISiStheMulTIFoRMbOUNDaRY'
body = []
for k, v in params.items():
body.append('--' + BOUNDARY)
part_head = 'Content-Disposition: ' 'form-data; name="%s"' % k
body.append(part_head)
body.append('')
body.append(str(v))
 
for (filename, value) in [(self.image,self.filedata)]:
body.append('--' + BOUNDARY)
part_head = 'Content-Disposition: ' 'form-data; name="media"'
body.append(part_head + ';filename="%s"' % filename)
body.append('Content-Type: %s' % self.get_content_type())
body.append('')
body.append(value)
 
body.append("--" + BOUNDARY + "--")
body_txt = "\r\n".join(body)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
 
return content_type, body_txt
 
def get_content_type(self):
""" Get the content Type of the file """
if MIME_FLAG:
return mimetypes.guess_type(self.image)[0] or 'application/octet-stream'
else:
return 'application/octet-stream'
 
def get_filedata(self):
""" Get the file content """
if self.filedata is None:
self.filedata = file(self.image,'r').read()
else:
self.image = 'up.jpg'
 
 
 
def upload(self, image=None, message=None, post_to_twitter=False):
""" Upload the photo to TwitPic with an optional message.
Post to Twitter the link also (optional) """

 
BLOCKSIZE = 8192
body_txt = []
 
if image:
self.image = image
self.get_filedata()
fields = {'username': self.username, 'password': self.password}
 
if message is not None:
fields['message'] = message
 
content_type, body_txt = self.encode_multipart_formdata(fields)
url = self.upload_url
if post_to_twitter:
url = self.upload_post_url
 
try:
self.connection = httplib.HTTP(self.server)
self.connection.putrequest('POST', '/%s' %url)
self.connection.putheader('content-type',content_type)
self.connection.putheader('content-length', str(len(body_txt)))
self.connection.endheaders()
 
for i in range(0, len(body_txt), BLOCKSIZE):
self.connection.send(body_txt[i:i+BLOCKSIZE])
 
statusCode, statusMsg, headers = self.connection.getreply()
response = self.connection.file.read()
resp = parse_xml('mediaurl', response)
 
return resp
 
except:
return None

The constructor of the API receives parameters like the twitter username and password, the image (string containing the image file path) or instead, it's possible also pass the image bytes fileData to upload to the TwitPic. After that, you can call the method upload without parameters to upload the picture to TwitPic or if you set the flag post_to_twitter' to True (the default value is False) you can upload and after post the picture to your Twitter home line account.

The response is the URL link of the photo posted to TwitPic if it's done successfully or None if it happened some problem during the uploading. The next version release will handle the error codes in order to show the developers/users the specific error that happened during the uploading process.

Application Example

A small application that uses the s60twitpicApi is below. Copy the files to memory card or memory (depending on your PySymbian version). Don't forget to put the library API in a folder called lib inside of the python folder. If it's not created, create one yourself. The application will ask if you run it for the first time your twitter username and password. After you pass your twitter account, the application will save it in a config file, in order to use in the future preventing the abusive ask of the twitter log in information every time you run it.

You can define your default access point and you can upload photos taken from your mobile phone camera in real-time to your Twitpic account. Just select the option 'Take photo', point it where you want to take the snapshot, press the main key of the cellphone, and the photo taken will be uploaded directly to your TwitPic account.

TwitPickS60.py

""""
=======================
TwitPickS60
=======================
(c) 2009 Marcel Caraciolo
e-mail: caraciol@gmail.com
Released under the GNU General Public License
"""

 
 
import appuifw, e32, key_codes, camera, os
 
try:
import btsocket
except ImportError:
import socket as btsocket
 
from s60twitpic import *
 
 
TEXT_COLOR = (255,0,0)
PROGRESS_COLOR = (0, 255, 0)
 
 
if e32.pys60_version.split()[0] >= '1.9.1':
TWITTER_FILE = os.path.join(['c:','Data','python','instaTwitter.cfg'])
IMG_FILE = os.path.join(['c:','Data','python','instaTwitter.jpg'])
else:
TWITTER_FILE = os.path.join(['e:','python','instaTwitter.cfg'])
IMG_FILE = os.path.join(['e:','python','instaTwitter.jpg'])
 
 
def new_user():
global twitter_password
global twitter_user
 
mini_user = appuifw.query(u'Give the twitter username','text')
 
if not mini_user:
return
 
canvas.clear((255,255,255))
show_text(u"Welcome to TwitPickS60")
 
 
mini_password = appuifw.query(u'Give the twitter password','text')
 
if not mini_password:
return
 
canvas.clear((255,255,255))
show_text(u"Welcome to TwitPickS60")
 
 
params = {"user_name": str(mini_user) ,
"user_password": str(mini_password) }
 
try:
f = file(TWITTER_FILE,'w')
token = params['user_name'] + ',' + params['user_password']
f.write(token)
f.close()
load_user()
appuifw.note(u'Twitter User/Password saved!', 'info')
 
except:
appuifw.note(u"Could not save the twitter user/password", "error")
 
canvas.clear((255,255,255))
show_text(u"Welcome to TwitPickS60")
 
 
def load_user():
global twitter_user
global twitter_password
try:
listT = file(TWITTER_FILE).read().split(',')
twitter_user = listT[0]
twitter_password = listT[1]
except:
new_user()
 
 
def finder_cb(im):
canvas.blit(im)
 
 
def take_photo(pos=(0,0)):
global twitter_user
global twitter_password
 
canvas.bind(key_codes.EKeySelect, None)
camera.stop_finder()
 
show_text(u'Hold still!')
image = camera.take_photo(size = (640, 480))
 
s = canvas.size
canvas.blit(image,target=(0,0,s[0],(s[0]/4*3)), scale=1)
show_text(u'Uploading to TwitPickr...')
 
image.save(IMG_FILE)
 
params = {'username': str(twitter_user), 'password': str(twitter_password), 'photo': IMG_FILE}
 
api = TwitPicAPI(params['username'], params['password'], params['photo'])
 
ret = api.upload()
 
canvas.clear((255,255,255))
if ret:
show_text(u"Photo sent ok!")
canvas.clear((255,255,255))
show_text(u"Link: %s" % ret)
else:
show_text(u"Network error")
 
def start_viewfinder():
if twitter_user and twitter_password:
camera.start_finder(finder_cb, size=canvas.size)
canvas.bind(key_codes.EKeySelect, take_photo)
else:
appuifw.note(u"Give your Twitter Username/Password first", "error")
 
 
def show_text(txt):
s = canvas.size
canvas.text((10, s[1] / 2 - 15), txt, fill=TEXT_COLOR, font="title")
 
 
def quit():
app_lock.signal()
 
 
def access_point():
global ap_id
ap_id = btsocket.select_access_point()
apo = btsocket.access_point(ap_id)
btsocket.set_default_access_point(apo)
 
appuifw.app.exit_key_handler = quit
appuifw.app.title = u"TwitPicker"
appuifw.app.menu = [(u"Take photo", start_viewfinder),
(u"New user", new_user),
(u"Access point", access_point),
(u"Quit", quit)]
 
appuifw.app.body = canvas = appuifw.Canvas()
canvas.clear((255,255,255))
show_text(u"Welcome to TwitPickS60")
 
load_user()
app_lock = e32.Ao_lock()
app_lock.wait()


ScreenShots

Some screen-shots of the demo.

TwitS6001.jpg        TwitS6002.jpg        TwitS6003.jpg        TwitS6004.jpg        TwitS6005.jpg


Source Code

Donwload source code of all examples in this article: File:TwitPicS60.zip

This page was last modified on 2 July 2012, at 02:44.
151 page views in the last 30 days.