Add support for portable mode (bug 236)
[gpodder.git] / src / gpodder / my.py
bloba9d0ee879109fbaa45817f8224e275db4f39ee61
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
4 # gPodder - A media aggregator and podcast client
5 # Copyright (c) 2005-2009 Thomas Perl and the gPodder Team
7 # gPodder is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # gPodder is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 # my.py -- "my gPodder" service client
24 # Thomas Perl <thp@gpodder.org> 2008-12-08
27 import gpodder
28 _ = gpodder.gettext
30 from gpodder import util
32 ########################################################################
33 # Based on upload_test.py
34 # Copyright Michael Foord, 2004 & 2005.
35 # Released subject to the BSD License
36 # Please see http://www.voidspace.org.uk/documents/BSD-LICENSE.txt
37 # Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
38 # E-mail fuzzyman@voidspace.org.uk
39 ########################################################################
41 import urllib2
42 import mimetypes
43 import mimetools
44 import webbrowser
46 def encode_multipart_formdata(fields, files, BOUNDARY = '-----'+mimetools.choose_boundary()+'-----'):
47 """ Encodes fields and files for uploading.
48 fields is a sequence of (name, value) elements for regular form fields - or a dictionary.
49 files is a sequence of (name, filename, value) elements for data to be uploaded as files.
50 Return (content_type, body) ready for urllib2.Request instance
51 You can optionally pass in a boundary string to use or we'll let mimetools provide one.
52 """
53 CRLF = '\r\n'
54 L = []
55 if isinstance(fields, dict):
56 fields = fields.items()
57 for (key, value) in fields:
58 L.append('--' + BOUNDARY)
59 L.append('Content-Disposition: form-data; name="%s"' % key)
60 L.append('')
61 L.append(value)
62 for (key, filename, value) in files:
63 filetype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
64 L.append('--' + BOUNDARY)
65 L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
66 L.append('Content-Type: %s' % filetype)
67 L.append('')
68 L.append(value)
69 L.append('--' + BOUNDARY + '--')
70 L.append('')
71 body = CRLF.join(L)
72 content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
73 return content_type, body
75 def build_request(theurl, fields, files, txheaders=None):
76 """Given the fields to set and the files to encode it returns a fully formed urllib2.Request object.
77 You can optionally pass in additional headers to encode into the opject. (Content-type and Content-length will be overridden if they are set).
78 fields is a sequence of (name, value) elements for regular form fields - or a dictionary.
79 files is a sequence of (name, filename, value) elements for data to be uploaded as files.
80 """
81 content_type, body = encode_multipart_formdata(fields, files)
82 if not txheaders: txheaders = {}
83 txheaders['Content-type'] = content_type
84 txheaders['Content-length'] = str(len(body))
85 txheaders['User-agent'] = gpodder.user_agent
86 return urllib2.Request(theurl, body, txheaders)
89 class MygPodderClient(object):
90 def __init__(self, service_uri, username, password):
91 self.service_uri = service_uri
92 self.username = username
93 self.password = password
95 def open_website(self):
96 webbrowser.open(self.service_uri, new=1)
98 def download_subscriptions(self):
99 theurl = self.service_uri+"/getlist"
100 args = {'username': self.username, 'password': self.password}
101 args = '&'.join(('%s=%s' % a for a in args.items()))
102 url = theurl + '?' + args
103 opml_data = util.urlopen(url).read()
104 return opml_data
106 def upload_subscriptions(self, filename):
107 theurl = self.service_uri+'/upload'
108 action = 'update-subscriptions'
109 fields = {'username': self.username, 'password': self.password, 'action': 'update-subscriptions', 'protocol': '0'}
110 opml_file = ('opml', 'subscriptions.opml', open(filename).read())
112 result = urllib2.urlopen(build_request(theurl, fields, [opml_file])).read()
113 messages = []
115 success = False
117 if '@GOTOMYGPODDER' in result:
118 self.open_website()
119 messages.append(_('Please have a look at the website for more information.'))
121 if '@SUCCESS' in result:
122 messages.append(_('Subscriptions uploaded.'))
123 success = True
124 elif '@AUTHFAIL' in result:
125 messages.append(_('Authentication failed.'))
126 elif '@PROTOERROR' in result:
127 messages.append(_('Protocol error.'))
128 else:
129 messages.append(_('Unknown response.'))
131 return success, messages