2020-01-04 00:18:51 +00:00
local BD = require ( " ui/bidi " )
2017-04-19 15:59:45 +00:00
local DataStorage = require ( " datastorage " )
2019-04-14 20:43:27 +00:00
--local DownloadBackend = require("internaldownloadbackend")
2018-01-31 11:39:04 +00:00
--local DownloadBackend = require("luahttpdownloadbackend")
2019-04-14 20:43:27 +00:00
local DownloadBackend = require ( " epubdownloadbackend " )
2017-10-27 21:00:49 +00:00
local ReadHistory = require ( " readhistory " )
2017-04-19 15:59:45 +00:00
local FFIUtil = require ( " ffi/util " )
2017-08-11 14:28:25 +00:00
local InfoMessage = require ( " ui/widget/infomessage " )
2018-08-07 19:03:43 +00:00
local InputDialog = require ( " ui/widget/inputdialog " )
2017-08-11 14:28:25 +00:00
local LuaSettings = require ( " frontend/luasettings " )
local UIManager = require ( " ui/uimanager " )
2017-10-22 07:11:23 +00:00
local NetworkMgr = require ( " ui/network/manager " )
2017-08-11 14:28:25 +00:00
local WidgetContainer = require ( " ui/widget/container/widgetcontainer " )
2018-04-12 14:05:50 +00:00
local dateparser = require ( " lib.dateparser " )
2017-08-11 14:28:25 +00:00
local logger = require ( " logger " )
local util = require ( " util " )
local _ = require ( " gettext " )
local T = FFIUtil.template
2017-04-19 15:59:45 +00:00
2018-08-17 18:54:11 +00:00
local NewsDownloader = WidgetContainer : new {
name = " newsdownloader " ,
}
2017-04-19 15:59:45 +00:00
2017-05-14 08:46:12 +00:00
local initialized = false
2018-08-07 19:03:43 +00:00
local feed_config_file_name = " feed_config.lua "
2017-05-14 08:46:12 +00:00
local news_downloader_config_file = " news_downloader_settings.lua "
2020-03-27 13:21:20 +00:00
local news_downloader_settings
local config_key_custom_dl_dir = " custom_dl_dir "
2019-04-14 20:43:27 +00:00
local file_extension = " .epub "
2017-05-08 20:15:42 +00:00
local news_download_dir_name = " news "
local news_download_dir_path , feed_config_path
2017-04-19 15:59:45 +00:00
2017-08-11 14:28:25 +00:00
-- if a title looks like <title>blabla</title> it'll just be feed.title
-- if a title looks like <title attr="alb">blabla</title> then we get a table
-- where [1] is the title string and the attributes are also available
local function getFeedTitle ( possible_title )
if type ( possible_title ) == " string " then
2019-01-24 22:04:49 +00:00
return util.htmlEntitiesToUtf8 ( possible_title )
2017-08-11 14:28:25 +00:00
elseif possible_title [ 1 ] and type ( possible_title [ 1 ] ) == " string " then
2019-01-24 22:04:49 +00:00
return util.htmlEntitiesToUtf8 ( possible_title [ 1 ] )
2017-08-11 14:28:25 +00:00
end
end
-- there can be multiple links
-- for now we just assume the first link is probably the right one
-- @todo write unit tests
-- some feeds that can be used for unit test
-- http://fransdejonge.com/feed/ for multiple links
-- https://github.com/koreader/koreader/commits/master.atom for single link with attributes
local function getFeedLink ( possible_link )
local E = { }
if type ( possible_link ) == " string " then
return possible_link
elseif ( possible_link._attr or E ) . href then
return possible_link._attr . href
elseif ( ( possible_link [ 1 ] or E ) . _attr or E ) . href then
return possible_link [ 1 ] . _attr.href
end
end
2017-04-19 15:59:45 +00:00
function NewsDownloader : init ( )
self.ui . menu : registerToMainMenu ( self )
end
function NewsDownloader : addToMainMenu ( menu_items )
2017-05-14 08:46:12 +00:00
self : lazyInitialization ( )
2017-05-08 20:15:42 +00:00
menu_items.news_downloader = {
2017-04-19 15:59:45 +00:00
text = _ ( " News (RSS/Atom) downloader " ) ,
sub_item_table = {
{
text = _ ( " Download news " ) ,
2018-09-04 21:55:58 +00:00
keep_menu_open = true ,
2018-01-17 17:16:11 +00:00
callback = function ( )
Various Wi-Fi QoL improvements (#6424)
* Revamped most actions that require an internet connection to a new/fixed backend that allows forwarding the initial action and running it automatically once connected. (i.e., it'll allow you to set "Action when Wi-Fi is off" to "turn_on", and whatch stuff connect and do what you wanted automatically without having to re-click anywhere instead of showing you a Wi-Fi prompt and then not doing anything without any other feedback).
* Speaking of, fixed the "turn_on" beforeWifi action to, well, actually work. It's no longer marked as experimental.
* Consistently use "Wi-Fi" everywhere.
* On Kobo/Cervantes/Sony, implemented a "Kill Wi-Fi connection when inactive" system that will automatically disconnect from Wi-Fi after sustained *network* inactivity (i.e., you can keep reading, it'll eventually turn off on its own). This should be smart and flexible enough not to murder Wi-Fi while you need it, while still not keeping it uselessly on and murdering your battery.
(i.e., enable that + turn Wi-Fi on when off and enjoy never having to bother about Wi-Fi ever again).
* Made sending `NetworkConnected` / `NetworkDisconnected` events consistent (they were only being sent... sometimes, which made relying on 'em somewhat problematic).
* restoreWifiAsync is now only run when really needed (i.e., we no longer stomp on an existing working connection just for the hell of it).
* We no longer attempt to kill a bogus non-existent Wi-Fi connection when going to suspend, we only do it when it's actually needed.
* Every method of enabling Wi-Fi will now properly tear down Wi-Fi on failure, instead of leaving it in an undefined state.
* Fixed an issue in the fancy crash screen on Kobo/reMarkable that could sometime lead to the log excerpt being missing.
* Worked-around a number of sneaky issues related to low-level Wi-Fi/DHCP/DNS handling on Kobo (see the lengthy comments [below](https://github.com/koreader/koreader/pull/6424#issuecomment-663881059) for details). Fix #6421
Incidentally, this should also fix the inconsistencies experienced re: Wi-Fi behavior in Nickel when toggling between KOReader and Nickel (use NM/KFMon, and run a current FW for best results).
* For developers, this involves various cleanups around NetworkMgr and NetworkListener. Documentation is in-line, above the concerned functions.
2020-07-27 01:39:06 +00:00
NetworkMgr : runWhenOnline ( function ( ) self : loadConfigAndProcessFeedsWithUI ( ) end )
2018-01-17 17:16:11 +00:00
end ,
2017-04-19 15:59:45 +00:00
} ,
{
text = _ ( " Go to news folder " ) ,
callback = function ( )
local FileManager = require ( " apps/filemanager/filemanager " )
2019-06-09 13:40:49 +00:00
if self.ui . document then
self.ui : onClose ( )
end
2017-04-19 15:59:45 +00:00
if FileManager.instance then
2017-05-08 20:15:42 +00:00
FileManager.instance : reinit ( news_download_dir_path )
2017-04-19 15:59:45 +00:00
else
2017-05-08 20:15:42 +00:00
FileManager : showFiles ( news_download_dir_path )
2017-04-19 15:59:45 +00:00
end
end ,
} ,
{
text = _ ( " Remove news " ) ,
2018-09-04 21:55:58 +00:00
keep_menu_open = true ,
2017-05-14 08:46:12 +00:00
callback = function ( ) self : removeNewsButKeepFeedConfig ( ) end ,
} ,
2020-03-27 13:21:20 +00:00
{
text = _ ( " Never download images " ) ,
keep_menu_open = true ,
checked_func = function ( )
2021-03-06 21:44:18 +00:00
return news_downloader_settings : isTrue ( " never_download_images " )
2020-03-27 13:21:20 +00:00
end ,
callback = function ( )
2021-03-06 21:44:18 +00:00
news_downloader_settings : toggle ( " never_download_images " )
2020-03-27 13:21:20 +00:00
news_downloader_settings : flush ( )
end ,
} ,
2017-06-29 18:40:42 +00:00
{
text = _ ( " Settings " ) ,
2018-01-17 17:16:11 +00:00
sub_item_table = {
{
text = _ ( " Change feeds configuration " ) ,
2018-09-04 21:55:58 +00:00
keep_menu_open = true ,
2018-08-07 19:03:43 +00:00
callback = function ( ) self : changeFeedConfig ( ) end ,
} ,
{
2021-02-22 17:44:16 +00:00
text = _ ( " Set custom download folder " ) ,
2018-09-04 21:55:58 +00:00
keep_menu_open = true ,
2018-08-07 19:03:43 +00:00
callback = function ( ) self : setCustomDownloadDirectory ( ) end ,
2018-01-17 17:16:11 +00:00
} ,
} ,
2017-06-29 18:40:42 +00:00
} ,
2017-04-19 15:59:45 +00:00
{
text = _ ( " Help " ) ,
2018-09-04 21:55:58 +00:00
keep_menu_open = true ,
2017-04-19 15:59:45 +00:00
callback = function ( )
UIManager : show ( InfoMessage : new {
2017-06-29 18:40:42 +00:00
text = T ( _ ( " News downloader retrieves RSS and Atom news entries and stores them to: \n %1 \n \n Each entry is a separate html file, that can be browsed by KOReader file manager. \n Items download limit can be configured in Settings. " ) ,
2020-01-04 00:18:51 +00:00
BD.dirpath ( news_download_dir_path ) )
2017-04-19 15:59:45 +00:00
} )
end ,
} ,
} ,
}
end
2017-05-14 08:46:12 +00:00
function NewsDownloader : lazyInitialization ( )
if not initialized then
logger.dbg ( " NewsDownloader: obtaining news folder " )
2020-03-27 13:21:20 +00:00
news_downloader_settings = LuaSettings : open ( ( " %s/%s " ) : format ( DataStorage : getSettingsDir ( ) , news_downloader_config_file ) )
2017-05-14 08:46:12 +00:00
if news_downloader_settings : has ( config_key_custom_dl_dir ) then
news_download_dir_path = news_downloader_settings : readSetting ( config_key_custom_dl_dir )
else
2017-10-27 21:00:49 +00:00
news_download_dir_path = ( " %s/%s/ " ) : format ( DataStorage : getFullDataDir ( ) , news_download_dir_name )
2017-05-14 08:46:12 +00:00
end
if not lfs.attributes ( news_download_dir_path , " mode " ) then
logger.dbg ( " NewsDownloader: Creating initial directory " )
lfs.mkdir ( news_download_dir_path )
end
2018-08-07 19:03:43 +00:00
feed_config_path = news_download_dir_path .. feed_config_file_name
2017-05-14 08:46:12 +00:00
if not lfs.attributes ( feed_config_path , " mode " ) then
logger.dbg ( " NewsDownloader: Creating initial feed config. " )
2018-08-07 19:03:43 +00:00
FFIUtil.copyFile ( FFIUtil.joinPath ( self.path , feed_config_file_name ) ,
2017-05-14 08:46:12 +00:00
feed_config_path )
end
initialized = true
end
end
2017-04-19 15:59:45 +00:00
function NewsDownloader : loadConfigAndProcessFeeds ( )
2019-04-30 22:37:03 +00:00
local UI = require ( " ui/trapper " )
UI : info ( " Loading news feed config… " )
2017-05-14 08:46:12 +00:00
logger.dbg ( " force repaint due to upcoming blocking calls " )
2017-04-19 15:59:45 +00:00
2017-05-08 20:15:42 +00:00
local ok , feed_config = pcall ( dofile , feed_config_path )
2017-04-19 15:59:45 +00:00
if not ok or not feed_config then
2019-04-30 22:37:03 +00:00
UI : info ( T ( _ ( " Invalid configuration file. Detailed error message: \n %1 " ) , feed_config ) )
2017-04-19 15:59:45 +00:00
return
end
if # feed_config <= 0 then
2018-01-30 16:00:38 +00:00
logger.err ( ' NewsDownloader: empty feed list. ' , feed_config_path )
2017-04-19 15:59:45 +00:00
return
end
2021-03-06 21:44:18 +00:00
local never_download_images = news_downloader_settings : isTrue ( " never_download_images " )
2020-03-27 13:21:20 +00:00
2017-05-08 20:15:42 +00:00
local unsupported_feeds_urls = { }
2021-03-06 21:44:18 +00:00
local total_feed_entries = # feed_config
2017-04-19 15:59:45 +00:00
for idx , feed in ipairs ( feed_config ) do
local url = feed [ 1 ]
local limit = feed.limit
2017-10-29 21:23:08 +00:00
local download_full_article = feed.download_full_article == nil or feed.download_full_article
2020-03-27 13:21:20 +00:00
local include_images = not never_download_images and feed.include_images
2020-06-04 20:58:14 +00:00
local enable_filter = feed.enable_filter or feed.enable_filter == nil
local filter_element = feed.filter_element or feed.filter_element == nil
2017-04-19 15:59:45 +00:00
if url and limit then
2020-01-04 00:18:51 +00:00
local feed_message = T ( _ ( " Processing %1/%2: \n %3 " ) , idx , total_feed_entries , BD.url ( url ) )
2019-05-15 19:31:46 +00:00
UI : info ( feed_message )
2020-06-04 20:58:14 +00:00
NewsDownloader : processFeedSource ( url , tonumber ( limit ) , unsupported_feeds_urls , download_full_article , include_images , feed_message , enable_filter , filter_element )
2017-04-19 15:59:45 +00:00
else
logger.warn ( ' NewsDownloader: invalid feed config entry ' , feed )
end
end
2017-05-08 20:15:42 +00:00
if # unsupported_feeds_urls <= 0 then
2019-04-30 22:37:03 +00:00
UI : info ( " Downloading news finished. " )
2017-05-08 20:15:42 +00:00
else
local unsupported_urls = " "
for k , url in pairs ( unsupported_feeds_urls ) do
unsupported_urls = unsupported_urls .. url
if k ~= # unsupported_feeds_urls then
2020-01-04 00:18:51 +00:00
unsupported_urls = BD.url ( unsupported_urls ) .. " , "
2017-05-08 20:15:42 +00:00
end
end
2019-04-30 22:37:03 +00:00
UI : info ( T ( _ ( " Downloading news finished. Could not process some feeds. Unsupported format in: %1 " ) , unsupported_urls ) )
2017-05-08 20:15:42 +00:00
end
Various Wi-Fi QoL improvements (#6424)
* Revamped most actions that require an internet connection to a new/fixed backend that allows forwarding the initial action and running it automatically once connected. (i.e., it'll allow you to set "Action when Wi-Fi is off" to "turn_on", and whatch stuff connect and do what you wanted automatically without having to re-click anywhere instead of showing you a Wi-Fi prompt and then not doing anything without any other feedback).
* Speaking of, fixed the "turn_on" beforeWifi action to, well, actually work. It's no longer marked as experimental.
* Consistently use "Wi-Fi" everywhere.
* On Kobo/Cervantes/Sony, implemented a "Kill Wi-Fi connection when inactive" system that will automatically disconnect from Wi-Fi after sustained *network* inactivity (i.e., you can keep reading, it'll eventually turn off on its own). This should be smart and flexible enough not to murder Wi-Fi while you need it, while still not keeping it uselessly on and murdering your battery.
(i.e., enable that + turn Wi-Fi on when off and enjoy never having to bother about Wi-Fi ever again).
* Made sending `NetworkConnected` / `NetworkDisconnected` events consistent (they were only being sent... sometimes, which made relying on 'em somewhat problematic).
* restoreWifiAsync is now only run when really needed (i.e., we no longer stomp on an existing working connection just for the hell of it).
* We no longer attempt to kill a bogus non-existent Wi-Fi connection when going to suspend, we only do it when it's actually needed.
* Every method of enabling Wi-Fi will now properly tear down Wi-Fi on failure, instead of leaving it in an undefined state.
* Fixed an issue in the fancy crash screen on Kobo/reMarkable that could sometime lead to the log excerpt being missing.
* Worked-around a number of sneaky issues related to low-level Wi-Fi/DHCP/DNS handling on Kobo (see the lengthy comments [below](https://github.com/koreader/koreader/pull/6424#issuecomment-663881059) for details). Fix #6421
Incidentally, this should also fix the inconsistencies experienced re: Wi-Fi behavior in Nickel when toggling between KOReader and Nickel (use NM/KFMon, and run a current FW for best results).
* For developers, this involves various cleanups around NetworkMgr and NetworkListener. Documentation is in-line, above the concerned functions.
2020-07-27 01:39:06 +00:00
NetworkMgr : afterWifiAction ( )
2017-04-19 15:59:45 +00:00
end
2019-04-30 22:37:03 +00:00
function NewsDownloader : loadConfigAndProcessFeedsWithUI ( )
local Trapper = require ( " ui/trapper " )
Trapper : wrap ( function ( )
self.loadConfigAndProcessFeeds ( )
end )
end
2020-06-04 20:58:14 +00:00
function NewsDownloader : processFeedSource ( url , limit , unsupported_feeds_urls , download_full_article , include_images , message , enable_filter , filter_element )
2017-08-11 14:28:25 +00:00
2018-01-31 11:39:04 +00:00
local ok , response = pcall ( function ( )
return DownloadBackend : getResponseAsString ( url )
end )
local feeds
if ok then
feeds = self : deserializeXMLString ( response )
end
if not ok or not feeds then
2017-05-08 20:15:42 +00:00
table.insert ( unsupported_feeds_urls , url )
return
end
local is_rss = feeds.rss and feeds.rss . channel and feeds.rss . channel.title and feeds.rss . channel.item and feeds.rss . channel.item [ 1 ] and feeds.rss . channel.item [ 1 ] . title and feeds.rss . channel.item [ 1 ] . link
2017-08-11 14:28:25 +00:00
local is_atom = feeds.feed and feeds.feed . title and feeds.feed . entry [ 1 ] and feeds.feed . entry [ 1 ] . title and feeds.feed . entry [ 1 ] . link
2017-05-08 20:15:42 +00:00
2019-04-30 22:37:03 +00:00
if is_atom then
ok = pcall ( function ( )
2020-06-04 20:58:14 +00:00
return self : processAtom ( feeds , limit , download_full_article , include_images , message , enable_filter , filter_element )
2019-04-30 22:37:03 +00:00
end )
elseif is_rss then
ok = pcall ( function ( )
2020-06-04 20:58:14 +00:00
return self : processRSS ( feeds , limit , download_full_article , include_images , message , enable_filter , filter_element )
2019-04-30 22:37:03 +00:00
end )
end
if not ok or ( not is_rss and not is_atom ) then
table.insert ( unsupported_feeds_urls , url )
end
2017-05-08 20:15:42 +00:00
end
2017-05-14 08:46:12 +00:00
function NewsDownloader : deserializeXMLString ( xml_str )
-- uses LuaXML https://github.com/manoelcampos/LuaXML
-- The MIT License (MIT)
-- Copyright (c) 2016 Manoel Campos da Silva Filho
2018-04-12 14:05:50 +00:00
-- see: koreader/plugins/newsdownloader.koplugin/lib/LICENSE_LuaXML
2017-05-14 08:46:12 +00:00
local treehdl = require ( " lib/handler " )
local libxml = require ( " lib/xml " )
--Instantiate the object the states the XML file as a Lua table
local xmlhandler = treehdl.simpleTreeHandler ( )
--Instantiate the object that parses the XML to a Lua table
local ok = pcall ( function ( )
libxml.xmlParser ( xmlhandler ) : parse ( xml_str )
end )
if not ok then return end
return xmlhandler.root
end
2020-06-04 20:58:14 +00:00
function NewsDownloader : processAtom ( feeds , limit , download_full_article , include_images , message , enable_filter , filter_element )
2017-05-08 20:15:42 +00:00
local feed_output_dir = string.format ( " %s%s/ " ,
news_download_dir_path ,
2019-05-14 17:10:41 +00:00
util.getSafeFilename ( getFeedTitle ( feeds.feed . title ) ) )
2017-05-08 20:15:42 +00:00
if not lfs.attributes ( feed_output_dir , " mode " ) then
lfs.mkdir ( feed_output_dir )
end
for index , feed in pairs ( feeds.feed . entry ) do
2017-08-11 14:28:25 +00:00
if limit ~= 0 and index - 1 == limit then
2017-05-08 20:15:42 +00:00
break
end
2019-05-15 19:31:46 +00:00
local article_message = T ( _ ( " %1 \n \n Fetching article %2/%3: " ) , message , index , limit == 0 and # feeds.rss . channel.item or limit )
2017-10-26 20:44:03 +00:00
if download_full_article then
2020-06-04 20:58:14 +00:00
self : downloadFeed ( feed , feed_output_dir , include_images , article_message , enable_filter , filter_element )
2017-10-26 20:44:03 +00:00
else
2019-05-26 14:22:50 +00:00
self : createFromDescription ( feed , feed.content [ 1 ] , feed_output_dir , include_images , article_message )
2017-10-26 20:44:03 +00:00
end
2017-05-08 20:15:42 +00:00
end
end
2017-04-19 15:59:45 +00:00
2020-06-04 20:58:14 +00:00
function NewsDownloader : processRSS ( feeds , limit , download_full_article , include_images , message , enable_filter , filter_element )
2017-04-19 15:59:45 +00:00
local feed_output_dir = ( " %s%s/ " ) : format (
2019-05-14 17:10:41 +00:00
news_download_dir_path , util.getSafeFilename ( util.htmlEntitiesToUtf8 ( feeds.rss . channel.title ) ) )
2017-04-19 15:59:45 +00:00
if not lfs.attributes ( feed_output_dir , " mode " ) then
lfs.mkdir ( feed_output_dir )
end
for index , feed in pairs ( feeds.rss . channel.item ) do
2017-08-11 14:28:25 +00:00
if limit ~= 0 and index - 1 == limit then
2017-04-19 15:59:45 +00:00
break
end
2019-05-15 19:31:46 +00:00
local article_message = T ( _ ( " %1 \n \n Fetching article %2/%3: " ) , message , index , limit == 0 and # feeds.rss . channel.item or limit )
2017-10-26 20:44:03 +00:00
if download_full_article then
2020-06-04 20:58:14 +00:00
self : downloadFeed ( feed , feed_output_dir , include_images , article_message , enable_filter , filter_element )
2017-10-26 20:44:03 +00:00
else
2019-05-26 11:46:25 +00:00
self : createFromDescription ( feed , feed.description , feed_output_dir , include_images , article_message )
2017-10-26 20:44:03 +00:00
end
2017-04-19 15:59:45 +00:00
end
end
2018-04-12 14:05:50 +00:00
local function parseDate ( dateTime )
-- uses lua-feedparser https://github.com/slact/lua-feedparser
-- feedparser is available under the (new) BSD license.
-- see: koreader/plugins/newsdownloader.koplugin/lib/LICENCE_lua-feedparser
local date = dateparser.parse ( dateTime )
return os.date ( " %y-%m-%d_%H-%M_ " , date )
end
local function getTitleWithDate ( feed )
2019-05-14 17:10:41 +00:00
local title = util.getSafeFilename ( getFeedTitle ( feed.title ) )
2018-04-12 14:05:50 +00:00
if feed.updated then
title = parseDate ( feed.updated ) .. title
elseif feed.pubDate then
title = parseDate ( feed.pubDate ) .. title
elseif feed.published then
title = parseDate ( feed.published ) .. title
end
return title
end
2020-06-04 20:58:14 +00:00
function NewsDownloader : downloadFeed ( feed , feed_output_dir , include_images , message , enable_filter , filter_element )
2019-05-15 19:31:46 +00:00
local title_with_date = getTitleWithDate ( feed )
2019-05-26 11:46:25 +00:00
local news_file_path = ( " %s%s%s " ) : format ( feed_output_dir ,
title_with_date ,
file_extension )
2017-08-11 14:28:25 +00:00
2019-05-26 11:46:25 +00:00
local file_mode = lfs.attributes ( news_file_path , " mode " )
2019-05-08 06:05:47 +00:00
if file_mode == " file " then
2019-05-26 11:46:25 +00:00
logger.dbg ( " NewsDownloader: " , news_file_path , " already exists. Skipping " )
2019-05-08 06:05:47 +00:00
else
2019-05-26 11:46:25 +00:00
logger.dbg ( " NewsDownloader: News file will be stored to : " , news_file_path )
2019-05-15 19:31:46 +00:00
local article_message = T ( _ ( " %1 \n %2 " ) , message , title_with_date )
2019-05-26 11:46:25 +00:00
local link = getFeedLink ( feed.link )
local html = DownloadBackend : loadPage ( link )
2020-06-04 20:58:14 +00:00
DownloadBackend : createEpub ( news_file_path , html , link , include_images , article_message , enable_filter , filter_element )
2019-05-08 06:05:47 +00:00
end
2017-05-08 20:15:42 +00:00
end
2019-05-26 14:22:50 +00:00
function NewsDownloader : createFromDescription ( feed , content , feed_output_dir , include_images , message )
2019-05-26 11:46:25 +00:00
local title_with_date = getTitleWithDate ( feed )
2017-10-26 20:44:03 +00:00
local news_file_path = ( " %s%s%s " ) : format ( feed_output_dir ,
2019-05-26 11:46:25 +00:00
title_with_date ,
file_extension )
local file_mode = lfs.attributes ( news_file_path , " mode " )
if file_mode == " file " then
logger.dbg ( " NewsDownloader: " , news_file_path , " already exists. Skipping " )
else
logger.dbg ( " NewsDownloader: News file will be stored to : " , news_file_path )
local article_message = T ( _ ( " %1 \n %2 " ) , message , title_with_date )
local footer = _ ( " This is just a description of the feed. To download the full article instead, go to the News Downloader settings and change 'download_full_article' to 'true'. " )
2017-10-26 20:44:03 +00:00
2019-05-26 11:46:25 +00:00
local html = string.format ( [ [ < ! DOCTYPE html >
2017-10-26 20:44:03 +00:00
< html >
< head >< meta charset = ' UTF-8 ' >< title >% s </ title ></ head >
< body >< header >< h2 >% s </ h2 ></ header >< article >% s </ article >
< br >< footer >< small >% s </ small ></ footer >
</ body >
2019-05-26 14:22:50 +00:00
</ html > ] ] , feed.title , feed.title , content , footer )
2019-05-26 11:46:25 +00:00
local link = getFeedLink ( feed.link )
DownloadBackend : createEpub ( news_file_path , html , link , include_images , article_message )
end
2017-10-26 20:44:03 +00:00
end
2017-05-14 08:46:12 +00:00
function NewsDownloader : removeNewsButKeepFeedConfig ( )
logger.dbg ( " NewsDownloader: Removing news from : " , news_download_dir_path )
for entry in lfs.dir ( news_download_dir_path ) do
2018-08-07 19:03:43 +00:00
if entry ~= " . " and entry ~= " .. " and entry ~= feed_config_file_name then
2017-05-14 08:46:12 +00:00
local entry_path = news_download_dir_path .. " / " .. entry
local entry_mode = lfs.attributes ( entry_path , " mode " )
if entry_mode == " file " then
2018-08-07 19:03:43 +00:00
os.remove ( entry_path )
2017-05-14 08:46:12 +00:00
elseif entry_mode == " directory " then
FFIUtil.purgeDir ( entry_path )
end
end
end
UIManager : show ( InfoMessage : new {
text = _ ( " All news removed. " )
} )
end
function NewsDownloader : setCustomDownloadDirectory ( )
require ( " ui/downloadmgr " ) : new {
onConfirm = function ( path )
logger.dbg ( " NewsDownloader: set download directory to: " , path )
news_downloader_settings : saveSetting ( config_key_custom_dl_dir , ( " %s/ " ) : format ( path ) )
news_downloader_settings : flush ( )
2017-05-17 20:24:49 +00:00
2018-08-07 19:03:43 +00:00
logger.dbg ( " NewsDownloader: Coping to new download folder previous feed_config_file_name from: " , feed_config_path )
FFIUtil.copyFile ( feed_config_path , ( " %s/%s " ) : format ( path , feed_config_file_name ) )
2017-05-17 20:24:49 +00:00
initialized = false
self : lazyInitialization ( )
2017-05-14 08:46:12 +00:00
end ,
} : chooseDir ( )
end
2018-08-07 19:03:43 +00:00
function NewsDownloader : changeFeedConfig ( )
local feed_config_file = io.open ( feed_config_path , " rb " )
local config = feed_config_file : read ( " *all " )
feed_config_file : close ( )
local config_editor
config_editor = InputDialog : new {
2020-01-04 00:18:51 +00:00
title = T ( _ ( " Config: %1 " ) , BD.filepath ( feed_config_path ) ) ,
2018-08-07 19:03:43 +00:00
input = config ,
input_type = " string " ,
2019-12-06 21:55:35 +00:00
para_direction_rtl = false , -- force LTR
2018-08-07 19:03:43 +00:00
fullscreen = true ,
condensed = true ,
allow_newline = true ,
cursor_at_end = false ,
add_nav_bar = true ,
reset_callback = function ( )
return config
end ,
save_callback = function ( content )
if content and # content > 0 then
local parse_error = util.checkLuaSyntax ( content )
if not parse_error then
local syntax_okay , syntax_error = pcall ( loadstring ( content ) )
if syntax_okay then
feed_config_file = io.open ( feed_config_path , " w " )
feed_config_file : write ( content )
feed_config_file : close ( )
return true , _ ( " Configuration saved " )
else
return false , T ( _ ( " Configuration invalid: %1 " ) , syntax_error )
end
else
return false , T ( _ ( " Configuration invalid: %1 " ) , parse_error )
end
end
return false , _ ( " Configuration empty " )
end ,
}
UIManager : show ( config_editor )
config_editor : onShowKeyboard ( )
end
2017-10-27 21:00:49 +00:00
function NewsDownloader : onCloseDocument ( )
local document_full_path = self.ui . document.file
2018-03-11 14:05:30 +00:00
if document_full_path and news_download_dir_path and news_download_dir_path == string.sub ( document_full_path , 1 , string.len ( news_download_dir_path ) ) then
2017-10-27 21:00:49 +00:00
logger.dbg ( " NewsDownloader: document_full_path: " , document_full_path )
logger.dbg ( " NewsDownloader: news_download_dir_path: " , news_download_dir_path )
logger.dbg ( " NewsDownloader: removing NewsDownloader file from history. " )
ReadHistory : removeItemByPath ( document_full_path )
2020-05-19 16:21:58 +00:00
local doc_dir = util.splitFilePathName ( document_full_path )
self.ui : setLastDirForFileBrowser ( doc_dir )
2017-10-27 21:00:49 +00:00
end
end
2017-04-19 15:59:45 +00:00
return NewsDownloader