/usr/share/pyshared/advancedcaching/downloader.py is in agtl 0.8.0.3-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 | #!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright (C) 2010 Daniel Fett
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author: Daniel Fett agtl@danielfett.de
# Jabber: fett.daniel@jaber.ccc.de
# Bugtracker and GIT Repository: http://github.com/webhamster/advancedcaching
#
import logging
logger = logging.getLogger('downloader')
class FileDownloader():
USER_AGENT = 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; de; rv:1.9.0.12) Gecko/2009070811 Windows NT Firefox/3.1'
opener_installed = False
def __init__(self, username, password, cookiefile, login_callback):
self.username = username
self.password = password
self.cookiefile = cookiefile
self.logged_in = False
from socket import setdefaulttimeout
setdefaulttimeout(30)
self.opener_installed = False
self.login_callback = login_callback
def update_userdata(self, username, password):
from os import path, remove
self.username = username
self.password = password
self.logged_in = False
if path.exists(self.cookiefile):
try:
remove(self.cookiefile)
except:
logger.info("Could not remove cookie file?!")
pass
def login(self):
if self.username == '' or self.password == '':
raise Exception("Please configure your username/password and restart the application")
logger.info("Checking Login status")
from cookielib import LWPCookieJar
cj = LWPCookieJar(self.cookiefile)
if not self.opener_installed:
from urllib2 import build_opener, install_opener, HTTPCookieProcessor
opener = build_opener(HTTPCookieProcessor(cj))
install_opener(opener)
self.opener_installed = True
try:
cj.load()
logger.info("Loaded cookie file")
except:
logger.info("Couldn't load cookie file")
else:
logger.info("Checking if still logged in...")
url = 'http://www.geocaching.com/seek/nearest.aspx'
page = self.get_reader(url, login = False)
for line in page:
if 'You are logged in as' in line:
self.logged_in = True
logger.info("Seems as we're still logged in")
page.close()
return
elif 'You are not logged in.' in line:
logger.info("Nope, not logged in anymore")
page.close()
break
logger.info("Logging in")
url, values = self.login_callback(self.username, self.password)
page = self.get_reader(url, values, login = False)
for line in page:
if 'You are logged in as' in line:
break
elif 'You are not logged in.' in line or 'combination does not match' in line:
raise Exception("Wrong password or username!")
else:
logger.info("Seems as if the language is set to something other than english")
raise Exception("Please go to geocaching.com and set the website language to english!")
logger.info("Great success.")
self.logged_in = True
try:
cj.save()
except Exception, e:
logger.info("Could not save cookies: %s" % e)
def get_reader(self, url, values=None, data=None, login = True):
from urllib import urlencode
from urllib2 import Request, urlopen
if login and not self.logged_in:
self.login()
if values == None and data == None:
req = Request(url)
self.add_headers(req)
return urlopen(req)
elif data == None:
if (isinstance(values, dict)):
values = urlencode( values)
req = Request(url, values)
self.add_headers(req)
return urlopen(req)
elif values == None:
content_type, body = data
req = Request(url)
req.add_header('Content-Type', content_type)
req.add_header('Content-Length', len(str(body)))
self.add_headers(req)
req.add_data(body)
return urlopen(req)
def encode_multipart_formdata(self, fields, files):
"""
fields is a sequence of (name, value) elements for regular form fields.
files is a sequence of (name, filename, value) elements for data to be uploaded as files
Return (content_type, body) ready for httplib.HTTP instance
"""
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for (key, value) in fields:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key, filename, value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename))
L.append('Content-Type: %s' % self.get_content_type(filename))
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
@staticmethod
def get_content_type(filename):
import mimetypes
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
def add_headers(self, req):
req.add_header('User-Agent', self.USER_AGENT)
req.add_header('Cache-Control', 'no-cache')
req.add_header('Pragma', 'no-cache')
|