Monday, February 28, 2022

npm install -g

As of about npm v5.0.0, the `npm install` command no longer installs from a directory. It is now an alias for `npm link`. This is fine in many cases, but `npm link` already existed and sometimes what one wants to do is install: not link.

For example, if a locally developed package is being installed globally so that all users can run a command it provides, it is generally best to install the package globally rather than link it, so that it is independent of the directory it was installed from.

Fortunately, it is not too difficult to overcome the elimination of this install option:

  • cd <package-directory>
  • npm pack
  • npm install -g <package>-<version>.tgz

This works because when installing from a tgz file, `npm install` still installs rather than linking.

Saturday, February 26, 2022

Worthless Guarantees from AliExpress and Netac Official Store

 I purchased an NVME SSD from Netac Official Store via AliExpress.

It is offered with "75-Day Buyer Protection Money Back Guarantee":

We promise your money back if the item you received is not as described, or if your item is not delivered within the Buyer Protection period. You can get a refund 15 days after the claim process finishes. This guarantee is in addition to and does not limit your statutory rights as a consumer, as granted by all mandatory laws and regulations applicable in your country of residence.

The package was delivered via postal service.

My local post office delivered the package to the wrong address and updated status to delivered.

I contacted my local post office and they confirmed that they delivered the package to the wrong address. They attempted to recover the package and deliver it to me but were unable to do so. They deemed the package to be lost.

My local post office cannot compensate me for the loss but they are willing to pay compensation for the loss if the sender makes a claim through the origin post office.

But AliExpress and the Netac Offical Store do not accept the emails I have forwarded from my post office confirming that they lost the package and did not deliver it to me.

They deem the communications from my local post office: "The evidence from NZPOST is not so clear to show the problems, please provide more clear evidence as required so that we can tell the problems obviously"

This is what NZ Post said:

Thank you for your patience. 

Sadly, your parcel has been delivered incorrectly, despite our attempts to recover this parcel from the incorrect address we have been unsuccessful. We have deemed this parcel to be missing. 

We recommend you contact the sender and request they initiate an enquiry/claim with the postal authority of the sending country. 

Please note claims for compensation for the loss or return of an international item can only be made by the sender from the country of origin. New Zealand Post has no provision for compensation for incoming international items. 

Our sincere apologies for the inconvenience caused by this incident.

How is this not clear? They made a mistake. They admit it. They are willing to pay compensation through the normal channels for international shipping.

International shipping is fraught with human error and acts of god that cause losses. Ships sink. Shipping containers go overboard. Warehouses go up in flames. All sorts of things. 

I don't mind that there was an error.

But obtuse refusal to accept the clear acceptance of fault and liability, to obtain the compensation offered and to send a replacement or refund is offensive.

AliExpress' and Netac Official Store's guarantees are worth nothing because they are in China and the guarantees are unenforceable from New Zealand, and neither AliExpress nor Netac Official Store are willing to honour them.

Update: NZ Post has changed their story. Now they say the package was scanned "near" my address and they don't know if it was delivered to my address and stolen or delivered to some other address. They maintain that in either case the package was "delivered" so they refuse to change the status in their tracking system. Still AliExpress is at fault for the delivery failure: they sent a valuable package with no signature required. Had a signature been required, the package would not have been left where it could be stolen. I would have gone in to pick it up and sign for it.

AliExpress has my money and I have nothing. Because they were negligent in how they sent it, not requiring a signature, allowing it to go missing rather than me receiving it. But from their perspective, all they have to say is: "The evidence from NZPOST is not so clear to show the problems,please provide more clear evidence as required so that we can tell the problems obviously"

The problem is: they have my money and I have nothing. But they don't care about that.

Saturday, February 19, 2022

Limitations of Calibre and Calibre-Web as an epub book viewer

When viewing an epub book using Calibre, one's position in the book is indicated as percent, in the bottom right corner of the reader window. This is OK for a small book but it does not show fractions of a percent and therefore is the same for many pages of a longer book. It does have the virtue that it is independent of the size of the reader window. Calibre maintains a constant position when the window is resized: at least some of the text is common between the larger and smaller window.

The Calibre-Web reading window is worse: it doesn't indicate position in the book at all. This is made worse by the fact that if one resizes the reader window the reader jumps to a different position in the book. If one alternates between a small and large window, just flipping back and forth, position gradually moves to the beginning of the current chapter. There is no practical way to get back to the original position except to go back to the start of the chapter then scan forward to the desired location. This is very poor UX.

In the case of Calibre-Web, the behaviour is a result of using epubjs to display the book. I have made a small test app that uses default configuration and it exhibits the same faults: no indication of position and position jumps when window is resized.

The epubjs package has many options. There may be options to display position and to maintain position when window is resized, but I haven't found them yet. I tried capturing and repositioning after resize, but it is a bit of a nightmare of rapid-fire events and deciding when to save and when to restore position. There does not appear to be any option to disable the automatic redisplay on window size change and there is essentially no documentation of the implementation.

As with so much software these days, the documentation of epubjs provides the syntax of the API but very little to nothing regarding the semantics.

There are some clues about getting page information in issue 744. None of this defines what is meant by "page" but most of the comments imply that what is meant is: what is presented in the reader window.

Calibre-Web has an inbuilt table-of contents for epub books but if it is opened the right side of the content goes off-screen with no scrollbar. It is impossible to read the text with the table of contents open.

Calibre-Web allows bookmarks to be saved but the presentation of them is as a cryptic string like "epubcfi(/6/8[id_4]!/4/2/1:0)". This is a standard epub cfi but it is not human friendly. Given a list of these, how would a normal person know which refers to what? There is no way to annotate them. In contrast, a bookmark in Firefox can be edited to change the title, icon, etc.

The bookmarks persist between browser sessions.  And they persist through clearing cookies and site data. This suggests that they are stored on the server. But presumably not in the book itself as each user could have different bookmarks.

It appears that Calibre-Web has its own database, in addition to the Calibre database it accesses. Default on Linux is ~/.calibre-web/app.db. This includes table 'bookmark' with fields user_id, book_id, format and bookmark_key, the latter two beeing epub and an epubcfi string. So, bookmarks are per user, per book and persistent across devices and sessions.

Both epub2 and epub3 have support for page lists but various posts suggest that almost no epub2 and few epub3 readers actually use them.

The navigation file provides some guidance on navigation for epub3.

A book might be published in hard copy, with a particular layout of pages. The same book in epub format will break the text into different sections, depending on font, window size, etc. One might be interested in what page of the original hard copy publication is being viewed, regardless of how many reader windows it takes to view the complete page, or one might be interested in pages as determined by the reader window: one reader window full is one page.

Is it possible to position the reader window at an arbitrary position in the text? If so, then what 'page' is the reader at when the displayed text starts at the second character of the book? Or the third? etc.

If the definition of "page" depends on the size of the reader window, font, screen resolution for displaying images, etc. then page number is only relevant in the current reader window context. If one reads the same book on a different system, with a different reader size, with a different font size, etc. then the page numbers will all be different. "Page 237" will contain different text depending on all these (and probably other) factors.

Counting characters might be more consistent: current display starts at character "1073648 of 27634287", for example. But this isn't very human friendly.

Pages are a familiar concept in paper books, but what do they mean in an e-book?

How does one return to the same position in the book, when one re-opens it?

How does one refer to a part of the book in computer friendly terms (where character offset might be fine) and human friendly terms?

Is it possible to make a fixed page list that is independent of the reader window size, screen resolution, font size, etc.? 

There is a good discussion of epub3 page lists at epubsecrets. This includes use cases where consistency across different media formats, independent of the individual reader details, is useful.

The epub3 spec includes page-list nav element.

epub3 has support for fixed layout documents, with the introduction pointing out that by default epub3 documents are intended to adapt to the reader with reflow, etc.

Firefox / Librewolf unsigned add-ons

In short:

Enable unsigned add-ons by setting xpinstall.signatures.required to false in about:config.

Make sure the add-on manifest.json has an id, as in the following:

   "browser_specific_settings": {
      "gecko": {
        "id": "zhongwen@example.org"
      }
    },

 Zip the add-on into an 'xpi' file:

    $ zip -r -FS ../zhongwen.xpi * --exclude '*.git*'

Then install the add-on from the about:addons page.

 

But it took me an unreasonably long time to learn to do this because Mozilla doesn't document it very well.

Mozilla has various guides to developing add-ons but they are all oriented towards having them signed by Mozilla. They say that it is possible to install unsigned add-ons to select versions of Firefox but give only hints about what is required.

Some add-ons that install successfully as a temporary add-on, via about:debugging, cannot be installed permanently as an unsigned add-on, with the unhelpful message:

Installation aborted because the add-on appears to be corrupt.

They could have omitted "because..." - it would have made the message no less informative.

Mozilla support gets reports of the message but offers no explanation. Multiple reports, with all sorts of complex details but no overview of how an add-on might be corrupt or how to diagnose the problem, just specific trial and error advice. Mozilla is getting to be as bad as Microsoft.

The browser console has more information:

1645324229834 addons.xpi WARN Invalid XPI: Error: Cannot find id for addon /home/ian/dev/zhongwen.xpi(resource://gre/modules/addons/XPIInstall.jsm:1531:19) JS Stack trace: loadManifest@XPIInstall.jsm:1531:19

Why isn't the error message to the user: Installation aborted because the add-on does not have an id? Or some such? None the less, if one jumps through enough esoteric hoops, the information is available.

So, how to provide an ID? 

This page gives some hints. 

The workshop gives some hints. Mostly it tells you that you don't have to set an ID explicitly and when you do have to set and ID explicitly. At the very end (did you read all the way through the irrelevant details to the last sentence?) it says:

See browser_specific_settings in manifest.json for the syntax of setting the extension ID.

Could they have made it any less obvious? I don't think so. To make it this obscure, one would have to be deliberately trying to make it difficult to succeed in any way other than having the add-on signed by Mozilla, and one would have to develop and refine the obscurity with diligence.

In any case, the documentation of browser_specific_settings describes the id, including the two supported formats.

So, I edited manifest.json of my plugin, adding:

   "browser_specific_settings": {
      "gecko": {
        "id": "zhongwen@example.org"
      }
    },

They don't say anything more about this format than: a string formatted like an email address, and the guidance that if it is a real email address it will attract spam. This suggests that it doesn't have to be a real email address: it just has to have the format of an email address. There is nothing about whether or how the address is used or validated, uniqueness constraints or anything else. Really, it just describes the syntax and that is all.

I then zipped the contents of the add-on directory, excluding the .git directory, to an xpi file (which is just a zip file with a unconventional extension):

    $ zip -r -FS ../zhongwen.xpi * --exclude '*.git*'

I also set 'xpinstall.signatures.required' to false via about:config.

I was then able to install the add-on.

Why do they need an ID when they don't need it to install temporarily? Obviously they don't need it, otherwise they would need it to install the add-on temporarily. It is an arbitrary restriction, making installation more difficult without adding any obvious value and possibly without adding any value at all. One more brick in the wall.

I have installed the add-on to Librewolf and a Nightly build of Firefox. It seems to work OK.

Zhongwen

Zhongwen is an add-on for Chrome and Firefox that looks up Chinese characters. I use it on Firefox.

I was using Calibre to view e-books but then I wanted to view them in a browser so I could use the Zhongwen add-on to look up the characters I don't know.

I installed Calibre-Web and began studying some of my Chinese books that were in pdf format. It worked great. I could read along and easily look up the characters I didn't know.

But then I tried reading a Chinese book in epub format and I couldn't look up the characters. The Zhongwen add-on wasn't working, except on the title line at the top of the page.

It turns out that the Zhongwen add-on doesn't work on content in an iframe and Calibre-Web presents the contents of epub books in an iframe.

I developed an enhancement of Zhongwen (see the issue85 branch) that works on content in iframes. I have only tried it with Calibre-Web but it works fine there. With this, I can view epub books via Calibre-Web and look up the Chinese characters I don't know with the modified Zhongwen add-on.

The only remaining problem is that Firefox no longer lets me install a plugin that isn't signed by Mozilla, unless I use an unbranded release. Security is good and it would be good if requiring signed add-ons was default, but removing all possibility of installing my own add-ons is going too far. Not every Firefox user is incompetent to create their own add-on and manage add-ons safely. If someone has access to my system to manipulate my add-ons, they can just replace the Firefox executable. Requiring signed add-ons is a limitation without benefit.

It is possible to install an unsigned add-on temporarily from about:debugging. But then the add-on must be re-installed every time Firefox is restarted.  

I installed an unbranded nightly build of Firefox but still there are hoops to jump in order to install the add-on permanently. It works fine installed temporarily but there is no easy to find and follow documentation about how to install a locally developed add-on permanently, only very lengthy procedures about how to register with Mozilla and publish an add-on, which is a very involved and time consuming process to learn and exercise.

So, at the moment I am stuck with loading the add-on temporarily. It seems that Mozilla, despite a good start, has decided that making the life of users difficult and less productive is the way to go.

I have submitted a pull request to Zhongwen but thus far there has been no response from the author. Who knows when or if an update of the add-on will allow it to work on content in an iframe. I will try to be patient. I have something that works well enough for my study in the meantime, though it is a nuisance having to use a different browser.

If the add-on isn't enhanced for too long, I will consider releasing my own version, but that requires getting involved with Mozilla's publishing process, which I would rather not do. It is really unfortunate that I can't put something up on GitHub or the like that people can download, review and install for themselves.

Maybe it is time to switch to a more permissive browser. Or maybe all the major browsers are now in the business of building walled gardens. It's a sad world. I wonder how long it will be before Firefox starts making it difficult to browser sites other than Mozilla's own sites and sites of those who fund it? They have already made it impossible to browse sites for which Mozilla deems the security to be inadequate. This was good when I could review the problem and manually override where appropriate, but more recent releases give no option to proceed to the site: it is simply and utterly blocked with an unhelpful message. Attempting to browse other sites results in an alert but, thus far, one can still proceed to the site: it is just a matter of dealing with the alerts and clicking through. Add-ons? There are no practical options: only Mozilla approved add-ons are allowed. The walls are going up and, no doubt, will become higher with time, then the excuse of lack of resources will be used to bring them in to reduce the scope of support. 

It's a sad world we live in. Mozilla used to develop good, free software. It still is, to the extent that I could fork Firefox and remove the restrictions, but I don't have time for that.

Labels