diff --git a/.busted b/.busted new file mode 100644 index 000000000..4343ab3d9 --- /dev/null +++ b/.busted @@ -0,0 +1,6 @@ +return { + default = { + verbose = true, + ROOT = "spec/front/unit", + }, +} diff --git a/.gitignore b/.gitignore index 6aabe7d43..e4a04a2d8 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ git-rev tags test/* *.tar +spec/unit/data emu diff --git a/Makefile b/Makefile index 1af9ad9ca..320f765db 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,11 @@ endif for f in $(INSTALL_FILES); do \ ln -sf ../../$$f $(INSTALL_DIR)/koreader/; \ done + # install front spec + cd $(INSTALL_DIR)/koreader/spec && test -e front || \ + ln -sf ../../../../spec ./front + cd $(INSTALL_DIR)/koreader/spec/front/unit && test -e data || \ + ln -sf ../../test ./data # install plugins cp -r plugins/* $(INSTALL_DIR)/koreader/plugins/ cp -rpL resources/fonts/* $(INSTALL_DIR)/koreader/fonts/ @@ -54,8 +59,16 @@ endif $(KOR_BASE)/$(OUTPUT_DIR)/luajit: $(MAKE) -C $(KOR_BASE) +$(INSTALL_DIR)/koreader/.busted: + test -e $(INSTALL_DIR)/koreader/.busted || \ + ln -sf ../../.busted $(INSTALL_DIR)/koreader + +testfront: $(INSTALL_DIR)/koreader/.busted + cd $(INSTALL_DIR)/koreader && busted -l ./luajit + test: $(MAKE) -C $(KOR_BASE) test + $(MAKE) testfront .PHONY: test diff --git a/frontend/MD5.lua b/frontend/MD5.lua index bf72a0d47..625624259 100644 --- a/frontend/MD5.lua +++ b/frontend/MD5.lua @@ -132,10 +132,10 @@ function MD5Transform(buf, input) c = MD5STEP(F4, c, d, a, b, input[2] + 0x2ad7d2bb, 15); b = MD5STEP(F4, b, c, d, a, input[9] + 0xeb86d391, 21); - buf[0] = (buf[0] + a)%0xffffffff; - buf[1] = (buf[1] + b)%0xffffffff; - buf[2] = (buf[2] + c)%0xffffffff; - buf[3] = (buf[3] + d)%0xffffffff; + buf[0] = band(buf[0] + a, 0xFFFFFFFF); + buf[1] = band(buf[1] + b, 0xFFFFFFFF); + buf[2] = band(buf[2] + c, 0xFFFFFFFF); + buf[3] = band(buf[3] + d, 0xFFFFFFFF); end function MD5Update(ctx, buf, len) diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index 3be7f8229..f89a3486d 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -354,7 +354,10 @@ function ReaderHighlight:saveHighlight() hl_item["drawer"] = self.view.highlight.saved_drawer table.insert(self.view.highlight.saved[page], hl_item) if self.selected_text.text ~= "" then - self:exportToClippings(page, hl_item) + -- disable exporting hightlights to My Clippings + -- since it's not potable and there is a better Evernote plugin + -- to do the same thing + --self:exportToClippings(page, hl_item) end if self.selected_text.pboxes then self:exportToDocument(page, hl_item) @@ -372,7 +375,8 @@ function ReaderHighlight:exportToClippings(page, item) clippings:write(self.document.file:gsub("(.*/)(.*)", "%2").."\n") clippings:write("- Koreader Highlight Page "..page.." ") clippings:write("| Added on "..os.date("%A, %b %d, %Y %I:%M:%S %p\n\n")) - clippings:write(item["text"].."\n") + -- My Clippings only holds one line of highlight + clippings:write(item["text"]:gsub("\n", " ").."\n") clippings:write("==========\n") clippings:close() os.setlocale(current_locale) diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index ecf56471c..aa0235e0f 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -1,4 +1,5 @@ local InputContainer = require("ui/widget/container/inputcontainer") +local Cache = require("cache") local Geom = require("ui/geometry") local Device = require("ui/device") local DocSettings = require("docsettings") @@ -301,6 +302,8 @@ function ReaderUI:onClose() self.start_pos = nil end UIManager:close(self.dialog) + -- serialize last used items for later launch + Cache:serialize() return true end diff --git a/frontend/document/djvudocument.lua b/frontend/document/djvudocument.lua index 015f89613..f323185b1 100644 --- a/frontend/document/djvudocument.lua +++ b/frontend/document/djvudocument.lua @@ -96,6 +96,14 @@ function DjvuDocument:getUsedBBox(pageno) return used end +function DjvuDocument:clipPagePNGFile(pos0, pos1, pboxes, drawer, filename) + return self.koptinterface:clipPagePNGFile(self, pos0, pos1, pboxes, drawer, filename) +end + +function DjvuDocument:clipPagePNGString(pos0, pos1, pboxes, drawer) + return self.koptinterface:clipPagePNGString(self, pos0, pos1, pboxes, drawer) +end + function DjvuDocument:getPageBBox(pageno) return self.koptinterface:getPageBBox(self, pageno) end diff --git a/frontend/document/document.lua b/frontend/document/document.lua index c04184607..7001dd32c 100644 --- a/frontend/document/document.lua +++ b/frontend/document/document.lua @@ -78,7 +78,6 @@ function Document:close() self.is_open = false self._document:close() end - Cache:serialize() end -- this might be overridden by a document implementation diff --git a/frontend/document/koptinterface.lua b/frontend/document/koptinterface.lua index 86eff3435..01229ad56 100644 --- a/frontend/document/koptinterface.lua +++ b/frontend/document/koptinterface.lua @@ -630,6 +630,54 @@ function KoptInterface:getOCRText(doc, pageno, tboxes) DEBUG("Not implemented yet") end +function KoptInterface:getClipPageContext(doc, pos0, pos1, pboxes, drawer) + assert(pos0.page == pos1.page) + assert(pos0.zoom == pos1.zoom) + local rect = nil + if pboxes and #pboxes > 0 then + local box = pboxes[1] + rect = Geom:new{ + x = box.x, y = box.y, + w = box.w, h = box.h, + } + for _, box in ipairs(pboxes) do + rect = rect:combine(Geom:new(box)) + end + else + local zoom = pos0.zoom or 1 + rect = { + x = math.min(pos0.x, pos1.x)/zoom, + y = math.min(pos0.y, pos1.y)/zoom, + w = math.abs(pos0.x - pos1.x)/zoom, + h = math.abs(pos0.y - pos1.y)/zoom + } + end + + local bbox = { + x0 = rect.x, y0 = rect.y, + x1 = rect.x + rect.w, + y1 = rect.y + rect.h + } + local kc = self:createContext(doc, pos0.page, bbox) + local page = doc._document:openPage(pos0.page) + page:getPagePix(kc) + page:close() + return kc, rect +end + +function KoptInterface:clipPagePNGFile(doc, pos0, pos1, pboxes, drawer, filename) + local kc = self:getClipPageContext(doc, pos0, pos1, pboxes, drawer) + kc:exportSrcPNGFile(pboxes, drawer, filename) + kc:free() +end + +function KoptInterface:clipPagePNGString(doc, pos0, pos1, pboxes, drawer) + local kc = self:getClipPageContext(doc, pos0, pos1, pboxes, drawer) + local png = kc:exportSrcPNGString(pboxes, drawer) + kc:free() + return png +end + --[[ get index of nearest word box around pos --]] diff --git a/frontend/document/pdfdocument.lua b/frontend/document/pdfdocument.lua index 7a6018c10..7e920e788 100644 --- a/frontend/document/pdfdocument.lua +++ b/frontend/document/pdfdocument.lua @@ -193,6 +193,14 @@ function PdfDocument:getLinkFromPosition(pageno, pos) return self.koptinterface:getLinkFromPosition(self, pageno, pos) end +function PdfDocument:clipPagePNGFile(pos0, pos1, pboxes, drawer, filename) + return self.koptinterface:clipPagePNGFile(self, pos0, pos1, pboxes, drawer, filename) +end + +function PdfDocument:clipPagePNGString(pos0, pos1, pboxes, drawer) + return self.koptinterface:clipPagePNGString(self, pos0, pos1, pboxes, drawer) +end + function PdfDocument:getPageBBox(pageno) return self.koptinterface:getPageBBox(self, pageno) end diff --git a/frontend/ui/device.lua b/frontend/ui/device.lua index 735b6ec43..2526b50c3 100644 --- a/frontend/ui/device.lua +++ b/frontend/ui/device.lua @@ -2,7 +2,7 @@ local KindlePowerD = require("ui/device/kindlepowerd") local KoboPowerD = require("ui/device/kobopowerd") local BasePowerD = require("ui/device/basepowerd") local Screen = require("ui/device/screen") --- util +local util = require("ffi/util") -- lfs local Device = { diff --git a/frontend/ui/widget/filechooser.lua b/frontend/ui/widget/filechooser.lua index 2d0d1bff3..df55f2e6e 100644 --- a/frontend/ui/widget/filechooser.lua +++ b/frontend/ui/widget/filechooser.lua @@ -3,6 +3,15 @@ local Screen = require("ui/screen") local UIManager = require("ui/uimanager") local DEBUG = require("dbg") -- lfs +local ffi = require("ffi") +ffi.cdef[[ +int strcoll (char *str1, char *str2); +]] + +-- string sort function respecting LC_COLLATE +local function strcoll(str1, str2) + return ffi.C.strcoll(ffi.cast("char*", str1), ffi.cast("char*", str2)) <= 0 +end local FileChooser = Menu:extend{ height = Screen:getHeight(), @@ -39,9 +48,9 @@ function FileChooser:genItemTableFromPath(path) end end end - table.sort(dirs) + table.sort(dirs, strcoll) if path ~= "/" then table.insert(dirs, 1, "..") end - table.sort(files) + table.sort(files, strcoll) local item_table = {} for _, dir in ipairs(dirs) do diff --git a/koreader-base b/koreader-base index ac9eea0e0..e94fe284a 160000 --- a/koreader-base +++ b/koreader-base @@ -1 +1 @@ -Subproject commit ac9eea0e045cc6e0a6021850fe804ae1c09748a3 +Subproject commit e94fe284a8d1bbbf3b09de2961b086073c0e0319 diff --git a/l10n/templates/koreader.pot b/l10n/templates/koreader.pot index e498f6571..b7cb0cabd 100644 --- a/l10n/templates/koreader.pot +++ b/l10n/templates/koreader.pot @@ -6,23 +6,28 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: https://github.com/koreader/koreader-base/issues\n" -"POT-Creation-Date: 2014-04-23 15:01+0000\n" +"POT-Creation-Date: 2014-05-15 09:54+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: reader.lua:119 +#: plugins/evernote.koplugin/main.lua:323 +msgid "" +" others." +msgstr "" + +#: reader.lua:115 msgid "" "-d start in debug mode" msgstr "" -#: reader.lua:121 +#: reader.lua:117 msgid "" "-h show this usage help" msgstr "" -#: reader.lua:120 +#: reader.lua:116 msgid "" "-p [rows] enable Lua code profiling" msgstr "" @@ -63,7 +68,7 @@ msgid "" "Apply" msgstr "" -#: frontend/apps/reader/modules/readertypeset.lua:54 +#: frontend/apps/reader/modules/readertypeset.lua:55 msgid "" "Auto" msgstr "" @@ -116,7 +121,7 @@ msgstr "" #: frontend/apps/reader/modules/readergoto.lua:36 #: frontend/ui/widget/confirmbox.lua:26 -#: plugins/evernote.koplugin/main.lua:92 +#: plugins/evernote.koplugin/main.lua:123 msgid "" "Cancel" msgstr "" @@ -203,44 +208,46 @@ msgid "" "Embedded Style" msgstr "" -#: plugins/evernote.koplugin/main.lua:245 +#: plugins/evernote.koplugin/main.lua:327 msgid "" "Error occurs when exporting book:" msgstr "" -#: plugins/evernote.koplugin/main.lua:140 -#: plugins/evernote.koplugin/main.lua:152 +#: plugins/evernote.koplugin/main.lua:177 +#: plugins/evernote.koplugin/main.lua:189 msgid "" "Error occurs when login:" msgstr "" -#: plugins/evernote.koplugin/main.lua:247 +#: plugins/evernote.koplugin/main.lua:329 msgid "" "Errors occur when exporting book:" msgstr "" -#: plugins/evernote.koplugin/main.lua:41 +#: plugins/evernote.koplugin/main.lua:42 +#: plugins/evernote.koplugin/main.lua:52 +#: plugins/evernote.koplugin/main.lua:64 msgid "" "Evernote" msgstr "" -#: plugins/evernote.koplugin/main.lua:56 +#: plugins/evernote.koplugin/main.lua:81 msgid "" "Export all notes in this book" msgstr "" -#: plugins/evernote.koplugin/main.lua:69 +#: plugins/evernote.koplugin/main.lua:97 msgid "" "Export all notes in your library" msgstr "" -#: plugins/evernote.koplugin/main.lua:238 -#: plugins/evernote.koplugin/main.lua:240 +#: plugins/evernote.koplugin/main.lua:320 +#: plugins/evernote.koplugin/main.lua:322 msgid "" "Exported notes in book:" msgstr "" -#: reader.lua:66 +#: reader.lua:62 msgid "" "File does not exist" msgstr "" @@ -327,12 +334,12 @@ msgid "" "Hyphenation" msgstr "" -#: reader.lua:126 +#: reader.lua:122 msgid "" "If you don't pass any path, the last viewed document will be opened" msgstr "" -#: reader.lua:123 +#: reader.lua:119 msgid "" "If you give the name of a directory instead of a file path, a file" msgstr "" @@ -357,7 +364,7 @@ msgid "" "Invert" msgstr "" -#: plugins/evernote.koplugin/main.lua:17 +#: plugins/evernote.koplugin/main.lua:16 msgid "" "Koreader Notes" msgstr "" @@ -387,23 +394,28 @@ msgid "" "Location" msgstr "" -#: plugins/evernote.koplugin/main.lua:45 -#: plugins/evernote.koplugin/main.lua:99 +#: plugins/evernote.koplugin/main.lua:140 +msgid "" +"Logging in please wait..." +msgstr "" + +#: plugins/evernote.koplugin/main.lua:55 +#: plugins/evernote.koplugin/main.lua:130 msgid "" "Login" msgstr "" -#: plugins/evernote.koplugin/main.lua:16 +#: plugins/evernote.koplugin/main.lua:15 msgid "" "Login to Evernote" msgstr "" -#: plugins/evernote.koplugin/main.lua:158 +#: plugins/evernote.koplugin/main.lua:195 msgid "" "Login to Evernote successfully" msgstr "" -#: plugins/evernote.koplugin/main.lua:45 +#: plugins/evernote.koplugin/main.lua:54 msgid "" "Logout" msgstr "" @@ -413,7 +425,7 @@ msgid "" "More" msgstr "" -#: reader.lua:81 +#: reader.lua:77 msgid "" "No reader engine for this file" msgstr "" @@ -423,7 +435,7 @@ msgid "" "Not supported device model!" msgstr "" -#: plugins/evernote.koplugin/main.lua:258 +#: plugins/evernote.koplugin/main.lua:339 msgid "" "Note: " msgstr "" @@ -439,7 +451,7 @@ msgid "" "Page" msgstr "" -#: frontend/ui/widget/touchmenu.lua:345 +#: frontend/ui/widget/touchmenu.lua:357 msgid "" "Page " msgstr "" @@ -480,7 +492,7 @@ msgid "" "RTL" msgstr "" -#: reader.lua:117 +#: reader.lua:113 msgid "" "Read all the books on your E-Ink reader" msgstr "" @@ -500,6 +512,11 @@ msgid "" "Render Quality" msgstr "" +#: plugins/evernote.koplugin/main.lua:48 +msgid "" +"Sandbox" +msgstr "" + #: frontend/ui/data/strings.lua:5 msgid "" "Screen Mode" @@ -520,7 +537,7 @@ msgid "" "Scroll Mode" msgstr "" -#: reader.lua:129 +#: reader.lua:125 msgid "" "See http://github.com/koreader/kindlepdfviewer for more info." msgstr "" @@ -587,7 +604,7 @@ msgid "" "Table of contents" msgstr "" -#: frontend/ui/widget/button.lua:78 +#: frontend/ui/widget/button.lua:80 msgid "" "Tap Button" msgstr "" @@ -597,17 +614,17 @@ msgid "" "Text Align" msgstr "" -#: plugins/evernote.koplugin/main.lua:76 +#: plugins/evernote.koplugin/main.lua:107 msgid "" "This may take several minutes..." msgstr "" -#: plugins/evernote.koplugin/main.lua:63 +#: plugins/evernote.koplugin/main.lua:91 msgid "" "This may take several seconds..." msgstr "" -#: reader.lua:128 +#: reader.lua:124 msgid "" "This software is licensed under the GPLv3." msgstr "" @@ -678,6 +695,12 @@ msgid "" "Writing screen to " msgstr "" +#: plugins/evernote.koplugin/main.lua:50 +#: plugins/evernote.koplugin/main.lua:71 +msgid "" +"Yinxiang" +msgstr "" + #: frontend/apps/reader/modules/readerzooming.lua:311 msgid "" "Zoom to fit content" @@ -708,8 +731,8 @@ msgid "" "Zoom to fit page width" msgstr "" -#: plugins/evernote.koplugin/main.lua:241 -#: plugins/evernote.koplugin/main.lua:248 +#: plugins/evernote.koplugin/main.lua:323 +#: plugins/evernote.koplugin/main.lua:330 msgid "" "and " msgstr "" @@ -724,7 +747,7 @@ msgid "" "cancel" msgstr "" -#: reader.lua:124 +#: reader.lua:120 msgid "" "chooser will show up and let you select a file" msgstr "" @@ -740,7 +763,7 @@ msgid "" "chose selected option" msgstr "" -#: frontend/apps/reader/modules/readertypeset.lua:48 +#: frontend/apps/reader/modules/readertypeset.lua:49 msgid "" "clear all external styles" msgstr "" @@ -762,7 +785,7 @@ msgid "" "close document" msgstr "" -#: frontend/ui/widget/menu.lua:449 +#: frontend/ui/widget/menu.lua:452 msgid "" "close menu" msgstr "" @@ -862,12 +885,12 @@ msgid "" "go to start" msgstr "" -#: frontend/ui/widget/menu.lua:451 +#: frontend/ui/widget/menu.lua:454 msgid "" "goto next page of the menu" msgstr "" -#: frontend/ui/widget/menu.lua:454 +#: frontend/ui/widget/menu.lua:457 msgid "" "goto previous page of the menu" msgstr "" @@ -967,7 +990,7 @@ msgid "" "move visible area up" msgstr "" -#: frontend/ui/widget/menu.lua:538 +#: frontend/ui/widget/menu.lua:541 msgid "" "no choices available" msgstr "" @@ -987,22 +1010,17 @@ msgid "" "on" msgstr "" -#: reader.lua:71 +#: reader.lua:67 msgid "" "opening file" msgstr "" -#: plugins/evernote.koplugin/main.lua:241 -msgid "" -"others." -msgstr "" - #: frontend/ui/data/strings.lua:55 msgid "" "page" msgstr "" -#: frontend/ui/widget/menu.lua:532 +#: frontend/ui/widget/menu.lua:535 msgid "" "page " msgstr "" @@ -1028,7 +1046,7 @@ msgid "" msgstr "" #: frontend/ui/widget/configdialog.lua:440 -#: frontend/ui/widget/menu.lua:463 +#: frontend/ui/widget/menu.lua:466 msgid "" "select current menu item" msgstr "" @@ -1074,7 +1092,7 @@ msgid "" "toggle bold" msgstr "" -#: reader.lua:116 +#: reader.lua:112 msgid "" "usage: ./reader.lua [OPTION] ... path" msgstr "" diff --git a/plugins/evernote.koplugin/clip.lua b/plugins/evernote.koplugin/clip.lua index aabca09f0..5c0526b73 100644 --- a/plugins/evernote.koplugin/clip.lua +++ b/plugins/evernote.koplugin/clip.lua @@ -1,3 +1,7 @@ +local DocumentRegistry = require("document/documentregistry") +local DocSettings = require("docsettings") +local DEBUG = require("dbg") +require("MD5") -- lfs local MyClipping = { @@ -157,7 +161,7 @@ function MyClipping:getTime(line) for k, v in pairs(months) do if line:find(k) then month = v - _, _, day = line:find(" (%d%d),") + _, _, day = line:find(" (%d?%d),") _, _, year = line:find(" (%d%d%d%d)") break end @@ -206,7 +210,22 @@ function MyClipping:getText(line) return line:match("^%s*(.-)%s*$") or "" end +-- get PNG string and md5 hash +function MyClipping:getImage(image) + --DEBUG("image", image) + local doc = DocumentRegistry:openDocument(image.file) + if doc then + local png = doc:clipPagePNGString(image.pos0, image.pos1, + image.pboxes, image.drawer) + --doc:clipPagePNGFile(image.pos0, image.pos1, + --image.pboxes, image.drawer, "/tmp/"..md5(png)..".png") + doc:close() + if png then return { png = png, hash = md5(png) } end + end +end + function MyClipping:parseHighlight(highlights, book) + --DEBUG("book", book.file) for page, items in pairs(highlights) do for _, item in ipairs(items) do local clipping = {} @@ -214,8 +233,21 @@ function MyClipping:parseHighlight(highlights, book) clipping.sort = "highlight" clipping.time = self:getTime(item.datetime or "") clipping.text = self:getText(item.text) + if item.pos0 and item.pos1 and + item.pos0.x and item.pos0.y and + item.pos1.x and item.pos1.y then + -- highlights in reflowing mode don't have page in pos + if item.pos0.page == nil then item.pos0.page = page end + if item.pos1.page == nil then item.pos1.page = page end + local image = {} + image.file = book.file + image.pos0, image.pos1 = item.pos0, item.pos1 + image.pboxes = item.pboxes + image.drawer = item.drawer + clipping.image = self:getImage(image) + end -- TODO: store chapter info when exporting highlights - if clipping.text and clipping.text ~= "" then + if clipping.text and clipping.text ~= "" or clipping.image then table.insert(book, { clipping }) end end @@ -232,7 +264,10 @@ function MyClipping:parseHistory() if ok and stored.highlight then local _, _, docname = path:find("%[.*%](.*)%.lua$") local title, author = self:getTitle(docname) + local path = DocSettings:getPathFromHistory(f) + local name = DocSettings:getNameFromHistory(f) clippings[title] = { + file = path .. "/" .. name, title = title, author = author, } @@ -250,6 +285,7 @@ function MyClipping:parseCurrentDoc(view) local _, _, docname = path:find(".*/(.*)") local title, author = self:getTitle(docname) clippings[title] = { + file = view.document.file, title = title, author = author, } diff --git a/plugins/evernote.koplugin/main.lua b/plugins/evernote.koplugin/main.lua index ded2d555b..aa95d49ff 100644 --- a/plugins/evernote.koplugin/main.lua +++ b/plugins/evernote.koplugin/main.lua @@ -38,19 +38,19 @@ function EvernoteExporter:init() end function EvernoteExporter:addToMainMenu(tab_item_table) - local domain = nil - if self.evernote_domain == "sandbox" then - domain = _("Sandbox") - elseif self.evernote_domain == "yinxiang" then - domain = _("Yinxiang") - else - domain = _("Evernote") - end table.insert(tab_item_table.plugins, { text = _("Evernote"), sub_item_table = { { text_func = function() + local domain = nil + if self.evernote_domain == "sandbox" then + domain = _("Sandbox") + elseif self.evernote_domain == "yinxiang" then + domain = _("Yinxiang") + else + domain = _("Evernote") + end return self.evernote_token and (_("Logout") .. " " .. domain) or _("Login") end, @@ -232,7 +232,8 @@ function EvernoteExporter:exportCurrentNotes(view) self:exportClippings(client, clippings) end -function EvernoteExporter:updateClippings(clippings, new_clippings) +function EvernoteExporter:updateHistoryClippings(clippings, new_clippings) + -- update clippings from history clippings for title, booknotes in pairs(new_clippings) do for chapter_index, chapternotes in ipairs(booknotes) do for note_index, note in ipairs(chapternotes) do @@ -242,6 +243,7 @@ function EvernoteExporter:updateClippings(clippings, new_clippings) or clippings[title][chapter_index][note_index].time ~= note.time or clippings[title][chapter_index][note_index].text ~= note.text or clippings[title][chapter_index][note_index].note ~= note.note then + DEBUG("found new notes in history", booknotes.title) clippings[title] = booknotes end end @@ -250,6 +252,18 @@ function EvernoteExporter:updateClippings(clippings, new_clippings) return clippings end +function EvernoteExporter:updateMyClippings(clippings, new_clippings) + -- only new titles or new notes in My clippings are updated to clippings + -- since appending is the only way to modify notes in My Clippings + for title, booknotes in pairs(new_clippings) do + if clippings[title] == nil or #clippings[title] < #booknotes then + DEBUG("found new notes in MyClipping", booknotes.title) + clippings[title] = booknotes + end + end + return clippings +end + function EvernoteExporter:exportAllNotes() local EvernoteClient = require("EvernoteClient") local client = EvernoteClient:new{ @@ -258,8 +272,8 @@ function EvernoteExporter:exportAllNotes() } local clippings = self.config:readSetting("clippings") or {} - clippings = self:updateClippings(clippings, self.parser:parseMyClippings()) - clippings = self:updateClippings(clippings, self.parser:parseHistory()) + clippings = self:updateHistoryClippings(clippings, self.parser:parseHistory()) + clippings = self:updateMyClippings(clippings, self.parser:parseMyClippings()) -- remove blank entries for title, booknotes in pairs(clippings) do -- chapter number is zero @@ -277,9 +291,13 @@ function EvernoteExporter:exportClippings(client, clippings) local export_count, error_count = 0, 0 local export_title, error_title for title, booknotes in pairs(clippings) do - -- skip exported booknotes - if booknotes.exported ~= true then - local ok, err = pcall(self.exportBooknotes, self, + if type(booknotes.exported) ~= "table" then + booknotes.exported = {} + end + -- check if booknotes are exported in this notebook + -- so that booknotes will still be exported after switching user account + if booknotes.exported[self.notebook_guid] ~= true then + local ok, err = pcall(self.exportBooknotes, self, client, title, booknotes) -- error reporting if not ok then @@ -290,10 +308,8 @@ function EvernoteExporter:exportClippings(client, clippings) DEBUG("Exported notes in book:", title) export_count = export_count + 1 export_title = title - booknotes.exported = true + booknotes.exported[self.notebook_guid] = true end - else - DEBUG("Skip exporting notes in book:", title) end end @@ -324,10 +340,22 @@ function EvernoteExporter:exportBooknotes(client, title, booknotes) }) --DEBUG("content", content) local note_guid = client:findNoteByTitle(title, self.notebook_guid) + local resources = {} + for _, chapter in ipairs(booknotes) do + for _, clipping in ipairs(chapter) do + if clipping.image then + table.insert(resources, { + image = clipping.image + }) + -- nullify clipping image after passing it to evernote client + clipping.image = nil + end + end + end if not note_guid then - client:createNote(title, content, {}, self.notebook_guid) + client:createNote(title, content, resources, {}, self.notebook_guid) else - client:updateNote(note_guid, title, content, {}, self.notebook_guid) + client:updateNote(note_guid, title, content, resources, {}, self.notebook_guid) end end diff --git a/plugins/evernote.koplugin/note.tpl b/plugins/evernote.koplugin/note.tpl index 7ceea52fd..ed592eda8 100644 --- a/plugins/evernote.koplugin/note.tpl +++ b/plugins/evernote.koplugin/note.tpl @@ -43,6 +43,9 @@
#{= htmlescape(clipping.text) }# + #{ if clipping.image then }# + + #{ end }#
#{ if clipping.note then }#
diff --git a/spec/unit/document_spec.lua b/spec/unit/document_spec.lua new file mode 100644 index 000000000..73ed68895 --- /dev/null +++ b/spec/unit/document_spec.lua @@ -0,0 +1,62 @@ +require "defaults" +require "libs/libkoreader-luagettext" +package.path = "?.lua;common/?.lua;frontend/?.lua" +package.cpath = "?.so;common/?.so;/usr/lib/lua/?.so" + +-- global einkfb for Screen +einkfb = require("ffi/framebuffer") +-- do not show SDL window +einkfb.dummy = true + +local Screen = require("ui/screen") +local DocSettings = require("docsettings") +G_reader_settings = DocSettings:open(".reader") +local DocumentRegistry = require("document/documentregistry") +local DEBUG = require("dbg") + +-- screen should be inited for crengine +Screen:init() + +describe("PDF document module", function() + local sample_pdf = "spec/front/unit/data/tall.pdf" + it("should open document", function() + doc = DocumentRegistry:openDocument(sample_pdf) + assert.truthy(doc) + end) + it("should get page dimensions", function() + local dimen = doc:getPageDimensions(1, 1, 0) + assert.are.same(dimen.w, 567) + assert.are.same(dimen.h, 1418) + end) + local pos0 = {page = 1, x = 0, y = 20} + local pos1 = {page = 1, x = 300, y = 120} + local pboxes = { + {x = 26, y = 42, w = 240, h = 22}, + {x = 48, y = 82, w = 185, h = 22}, + } + it("should clip page rect to PNG file", function() + doc:clipPagePNGFile(pos0, pos1, nil, nil, "/tmp/clip0.png") + doc:clipPagePNGFile(pos0, pos1, pboxes, "lighten", "/tmp/clip1.png") + end) + it("should clip page rect to PNG string", function() + local clip0 = doc:clipPagePNGString(pos0, pos1, nil, nil) + assert.truthy(clip0) + local clip1 = doc:clipPagePNGString(pos0, pos1, pboxes, "lighten") + assert.truthy(clip1) + end) + it("should close document", function() + doc:close() + end) +end) + +describe("EPUB document module", function() + local sample_epub = "spec/front/unit/data/leaves_of_grass.epub" + it("should open document", function() + doc = DocumentRegistry:openDocument(sample_epub) + assert.truthy(doc) + doc:close() + end) + it("should close document", function() + doc:close() + end) +end)