@ -1,6 +1,7 @@
local MultiInputDialog = require ( " ui/widget/multiinputdialog " )
local ButtonDialog = require ( " ui/widget/buttondialog " )
local InfoMessage = require ( " ui/widget/infomessage " )
local LoginDialog = require ( " ui/widget/logindialog " )
local lfs = require ( " libs/libkoreader-lfs " )
local OPDSParser = require ( " ui/opdsparser " )
local NetworkMgr = require ( " ui/networkmgr " )
@ -20,6 +21,7 @@ local socket = require('socket')
local http = require ( ' socket.http ' )
local https = require ( ' ssl.https ' )
local ltn12 = require ( ' ltn12 ' )
local mime = require ( ' mime ' )
local CatalogCacheItem = CacheItem : new {
size = 1024 , -- fixed size for catalog item
@ -214,12 +216,37 @@ function OPDSBrowser:genItemTableFromRoot()
return item_table
end
function OPDSBrowser : getBasicAuthentication ( host )
local authentications = G_reader_settings : readSetting ( " www-auth " ) or { }
return authentications [ host ]
end
function OPDSBrowser : setBasicAuthentication ( host , username , password )
local authentications = G_reader_settings : readSetting ( " www-auth " ) or { }
authentications [ host ] = {
username = username ,
password = password ,
}
G_reader_settings : saveSetting ( " www-auth " , authentications )
end
function OPDSBrowser : getAuthorizationHeader ( host )
local auth = self : getBasicAuthentication ( host )
if auth then
local authorization = auth.username .. ' : ' .. auth.password
return {
Authorization = " Basic " .. mime.b64 ( authorization ) ,
}
end
end
function OPDSBrowser : fetchFeed ( feed_url )
local headers , request , sink = { } , { } , { }
local parsed = url.parse ( feed_url )
request [ ' url ' ] = feed_url
request [ ' method ' ] = ' GET '
request [ ' sink ' ] = ltn12.sink . table ( sink )
request [ ' headers ' ] = self : getAuthorizationHeader ( parsed.host )
DEBUG ( " request " , request )
http.TIMEOUT , https.TIMEOUT = 10 , 10
local httpRequest = parsed.scheme == ' http ' and http.request or https.request
@ -230,13 +257,72 @@ function OPDSBrowser:fetchFeed(feed_url)
error ( code )
end
local xml = table.concat ( sink )
if xml ~= " " then
--DEBUG("xml", xml)
return xml
--DEBUG("response", code, headers, status)
if code == 401 and status and status : find ( " Unauthorized " ) then
self._coroutine = coroutine.running ( ) or self._coroutine
self : fetchWithLogin ( parsed.host , function ( )
return self : fetchFeed ( feed_url )
end )
if coroutine.running ( ) then
local result = coroutine.yield ( )
return result
end
else
local xml = table.concat ( sink )
if xml ~= " " then
--DEBUG("xml", xml)
return xml
end
end
end
function OPDSBrowser : fetchWithLogin ( host , callback )
self.login_dialog = LoginDialog : new {
title = _ ( " Login to OPDS server " ) ,
username = " " ,
buttons = {
{
{
text = _ ( " Cancel " ) ,
enabled = true ,
callback = function ( )
self : closeDialog ( )
end ,
} ,
{
text = _ ( " Login " ) ,
enabled = true ,
callback = function ( )
local username , password = self : getCredential ( )
self : setBasicAuthentication ( host , username , password )
self : closeDialog ( )
UIManager : scheduleIn ( 0.5 , function ( )
local res = callback ( )
if res then
coroutine.resume ( self._coroutine , res )
end
end )
end ,
} ,
} ,
} ,
width = Screen : getWidth ( ) * 0.8 ,
height = Screen : getHeight ( ) * 0.4 ,
}
self.login_dialog : onShowKeyboard ( )
UIManager : show ( self.login_dialog )
end
function OPDSBrowser : closeDialog ( )
self.login_dialog : onClose ( )
UIManager : close ( self.login_dialog )
end
function OPDSBrowser : getCredential ( )
return self.login_dialog : getCredential ( )
end
function OPDSBrowser : parseFeed ( feed_url )
local feed = nil
local hash = " opds|catalog| " .. feed_url
@ -388,6 +474,7 @@ function OPDSBrowser:downloadFile(title, format, remote_url)
local httpRequest = parsed.scheme == ' http ' and http.request or https.request
local r , c , h = httpRequest {
url = remote_url ,
headers = self : getAuthorizationHeader ( parsed.host ) ,
sink = ltn12.sink . file ( io.open ( local_path , " w " ) ) ,
}