Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add preferences window #176

Merged
merged 14 commits into from
Oct 26, 2022
Merged

Conversation

RoBaaaT
Copy link
Contributor

@RoBaaaT RoBaaaT commented Jul 31, 2022

This partially addresses #35 by implementing a basic preferences window.
The new preference window allows users to change the storage preference for citations (extra/note). The default was changed to 'note' to match the previous behaviour of the extension.
What is potentially missing is to move existing citations from the 'extra' to the 'note' format and vice-versa when the preference is changed by the user.

This pull request does not add the other potential preferences listed in #35, as the underlying functionality for those preferences has not been implemented yet.
It would probably make most sense to add those preferences to the window when the respective issues (#82, #45, #14) are addressed.

@Dominic-DallOsto
Copy link
Collaborator

Amazing, thanks a lot! I'll review this soon.

@Dominic-DallOsto
Copy link
Collaborator

Overall it looks good. Thanks!

Like you say, a way of migrating all your citations from one format to the other would be needed, otherwise Cita will fail to read any notes in the other format. Would you feel comfortable adding that? Otherwise, a good replacement for now might just be a description warning that changing this setting won't migrate notes - so it should only be changed when first setting up Cita.
In general a more detailed description for preferences could be handy. Perhaps as text next to the radio buttons. What do you think?

I also commented where you wait for window.Wikicite - I'm wondering if you can't just pass this in as the dialog is created?

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Aug 4, 2022

Thanks for reviewing!

I'll try adding the migration between notes and extras. It shouldn't be too difficult as all of the code for parsing and saving citations is already there in sourceItemWrapper.js.
The question is what we should do if we are migrating from note to extra and the extra field is already used for some items. Would it be enough to warn the user once that data could be overwritten or should we ask for each item that already has data in the extra field?

Regarding more detailed descriptions, perhaps it would be enough to just have some description text in the group box. Something like: "Cita can save citation data either as a note or in the extra field of library items. As using the extra field for citation data will make it impossible to use it for other purposes, the recommended option is storing citation data in notes. Changing this setting will migrate existing citation data to the new storage location for all items in the library."
Do you think that would work?

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Aug 5, 2022 via email

static/bootstrap.js Outdated Show resolved Hide resolved
@diegodlh
Copy link
Owner

diegodlh commented Aug 5, 2022

Thanks so much @RoBaaaT for working on this, and thank you @Dominic-DallOsto as usual for taking care of reviewing it.

the Wikicite object that is being passed through window.arguments is different from the one that is being set to window.Wikicite (which happens in bootstrap.js:117 on window load).

I added two comments above concerning this.

what we should do if we are migrating from note to extra and the extra field is already used for some items

As Dominic pointed out:

The function for writing to the extra field should be able to read/write
citations without affecting any other data that might be in there.
exactly

Thus, the following would be incorrect:

using the extra field for citation data will make it impossible to use it for other purposes

As described in #13, when I started working on this project, I decided to use the extra field. But it soon became obvious that Cita was storing too much information there (remember that we store metadata of the cited items), and the extra field became too cluttered. That's why in the end I decided to migrate to using note attachments.

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Aug 17, 2022

Hi, thanks again for your reviews and sorry for taking a while to respond.

I have now made some more changes to

  • add a short description text to the storage preference
  • pass the Prefs object as a window argument instead of using the weird hack to wait for it to be set from bootstrap.js
  • migrate the storage location of existing citation data when the preference is changed
  • give the preference dialog the same style as the rest of the Zotero app

Thanks for mentioning that storing citation data in the extra field does not mean that no other data can be stored in the field. I was not aware of that, and I have changed my proposed description text for the storage preference to reflect this (you can find it in wikicite.properties at wikicite.prefs.citation-storage-desc).

To make it so that the preference dialog would have the same style as the rest of Zotero, I had to change its "wrapper" file (preferences.html) from .html to .xul. I was not able to get the proper styling using the HTML version, despite including the Zotero stylesheets there, and I also could not find other examples of people using .html for additional windows in Zotero extensions, so changing to .xul - which everyone is using - seemed like the simplest option. Please let me know if you have other ideas.

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Aug 21, 2022 via email

@Dominic-DallOsto
Copy link
Collaborator

Hey, thanks a lot! This works really well. Just a couple of tiny things I left comments about. Then I think we're good to go!

@Dominic-DallOsto
Copy link
Collaborator

I added a formatString function for the progress. I just found that things could get weird in the unlikely case of a migration error, so catching and dealing with these might be nice?

Also, do the progress bar messages look cut-off for you, or is that just on my end?

But then I think (for real) it's all good!

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Oct 3, 2022

Sorry for taking a while, but with my latest change I've improved the migration process to either migrate all citation data or none at all if any errors occur (in that case the preference also remains unmodified). This is achieved by making all changes in a Zotero DB transaction, which is rolled back in the case of errors. If errors occur, the titles of items that caused the errors are collected and shown to the user in an alert. This way the user can manually check the citation data on these items and try to change the storage preference again at a later point in time.

The migration also now properly uses async/await calls, which makes it so that the progress reporting actually works as intended (although you might still only see the "migration finished" message if you have few items in your library).

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Oct 3, 2022

Also, do the progress bar messages look cut-off for you, or is that just on my end?

Do you mean the progress "window" in the bottom right? I've noticed too that those sometimes look cut off, but for me this is not consistent. Most of the time they look totally fine. Maybe this is an issue with the underlying Zotero.ProgressWindow implementation? I don't see anything in the Cita code that could be causing this.

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Oct 5, 2022 via email

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Oct 11, 2022 via email

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Oct 16, 2022

Do you think it looks nicer with bullet points in front of the paper names?

image

I haven't quite worked out the details, but I'm getting some odd errors like 'tags' not loaded for item (473/1/W77Z8GXU) after migrating from note to extra and back a few times. What happens is that I somehow end up with 2 citation notes per item.

It seems to happen when I deliberately introduce an error to one of the citation notes (eg. get citations from Wikidata for the item with DOI 10.1103/PhysRevD.40.83, then try and migrate to use the extra field. There'll be an error and the migration won't complete (as expected). Then if I delete the corrupt note from that item and try and migrate to extra again, I end up with items that have both the extra field and a citation note. Migrating back to citation now gives me 2 citation notes for each item.

Could the migration to an extra field not be correctly deleting the citation note after an error?

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Oct 16, 2022

Do you think it looks nicer with bullet points in front of the paper names?

Yes, that's definitely better, good idea. I think it makes it a lot more readable, especially with many "bad" items.

I haven't quite worked out the details, but I'm getting some odd errors like 'tags' not loaded for item (473/1/W77Z8GXU) after migrating from note to extra and back a few times. What happens is that I somehow end up with 2 citation notes per item.

In my testing I only had some minor issues with the detail display for selected items sometimes not being updated immediately after the migration, but this could always be resolved by just selecting another item or going to another collection. But I think it could be possible that there are some corner cases where the SourceItemWrapper instance that is being used in the UI code still has some stale data after running (or trying to run) the migration, which is then saved again when something is updated from the UI. I could imagine that this would lead to the types of issues you are seeing. I'll investigate this tomorrow and get back to you.

By the way, where are you seeing the errors you mention? In the Firefox developer console? I haven't gotten Zotero with debugging support working yet on my end, so I guess I'll have to look into that again...

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Oct 17, 2022

Yes, in the firefox dev console.

The instructions under ## Debugging section in the README here are fairly comprehensive. I'll try to do up a step by step guide some time soon. One important thing to note is to build with debug support, you need to run scripts/dir_build -t.
If you have a chance to test, could you let me know at what step you encounter an issue and I can try and guide you through?

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Oct 19, 2022

Hi, I tried setting up the debugging on my end, but am not able to get the custom-built Zotero instance to start (using Windows, which may or may not be contributing to the issue):

When I start the Zotero instance it does not start up properly but just shows a window with an error message saying that there was an unexpected "menuitem" element in some xul file. It also somehow gets completely stuck and I have to kill the process through taskmanager. I initially thought this may just be a bug in the Zotero HEAD version, but checking out the latest release tag and rebuilding still resulted in the same issue. Just to check, which Zotero version are you using for debugging on your end?

As a side node, I also had to specify --force for the npm i step in the Zotero build process, as there were some incompatible peer dependencies. But I guess this is just a matter of some upstream dependencies of Zotero having been updated since the latest version. In any case I don't think that this is causing the problem I'm seeing, as I would suspect "real" dependency issues to cause build failures, which did not happen for me.

Looking beyond the startup issue, I am actually able to connect the devtools, which is at least something I guess. Here I initially also had some trouble even figuring out how to enable and start remote debugging in the older Firefox version, as the process has apparently changed in the latest Firefox version. Maybe it would be good to document the steps in the README for others (1. enable remote debugging in the devtools settings; 2. restart Firefox; 3. select "connect..." in developer options), as it took me a while to figure this out.

I'll continue trying to get this working, it just might take some time. Maybe you have some feedback that can help.

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Oct 19, 2022

Hmm, that's odd. If it randomly helps, I'm using 6.0.2.SOURCE.d14a8b1d9 on Windows, but that just happens to be the last time I checked out.

Also if it helps, I used WSL instead of Cygwin for building Zotero. Basically, following the instructions here in the WSL terminal, but running ./fetch_xulrunner.sh -p w in step 5, and scripts/dir_build -p w -t in step 7.

Then I could run zotero.exe -debugger from the staging folder, and firefox.exe from the xulrunner folder. In both cases using a new profile -P and a new data directory in Zotero (settings -> advanced -> Folders -> Custom data directory). Follow the instructions here to set Zotero up to read the source files from Cita's dist directory. Also following the instructions to stop firefox from updating, and to enable the debug tools. To make life easier you can set your homepage to chrome://devtools/content/framework/connect/connect.xhtml.

Now connect the debug tools to port 6100, click "Main Process", and you should see something like this.

image

You should be able to set breakpoints in the code as shown (the blue arrow on line 31)

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Oct 20, 2022

Using WSL for building did the trick for me.
I can now at least start it with -debugger and connect from Firefox. When you do this, are you selecting the main process or just Cita (in the dialog from the screenshot below)?
image

I'm asking because I've found that breakpoints will only work if I select Cita, but I only get console output if i select the main process, which is kind of inconvenient. However the console output also does not show any Zotero debug messages, only warnings and errors, despite specifying -ZoteroDebugText when starting Zotero.

Regarding the issue with the migration you brought up, I've done some more investigation and it looks like the transaction is just not properly getting rolled back if a failure occurs, which causes all items besides the failed ones to be migrated anyways. But I do not yet understand why this is happening. Unfortunately the whole Zotero DB API is also quite sparsely documented, so I'm not sure if I'm just doing something wrong in the way I'm running the transaction.

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Oct 21, 2022

For me selecting the main process also works with breakpoints once I open the debugger tab like in the image above.

About the zotero log I'm not sure actually. On Ubuntu it all shows up in the console output when I run zotero from the command line, but I haven't got this to work in Windows. Does the Zotero JS debug console have the messages you're after?

Not sure if it helps but here and here the pattern seems to be using yield item.save().

I quickly checked the source here but didn't immediately find any answers. You're right, the documentation doesn't have much to go on.

@Dominic-DallOsto
Copy link
Collaborator

I'm asking because I've found that breakpoints will only work if I select Cita, but I only get console output if i select the main process, which is kind of inconvenient. However the console output also does not show any Zotero debug messages, only warnings and errors, despite specifying -ZoteroDebugText when starting Zotero.

Ahh, I found the solution for this here. Basically, on windows you need to put -ZoteroDebugText -console

@Dominic-DallOsto
Copy link
Collaborator

Dominic-DallOsto commented Oct 23, 2022

Not sure how but rethrowing the errors we get inside the loop seems to fix this problem for me. It doesn't make sense to me why this is the case but

Steps to reproduce for a fresh library:

  1. Add items by DOI - 10.1186/1471-230X-13-56 and 10.1103/PhysRevD.40.83. Get QIDs and sync citations for both. The second item will have an invalid note because of a bug I since fixed (I'll merge it here once we're done - it just makes debugging this error a bit more convenient)
  2. Migrate citations to the Extra field
  3. Without rethrowing, the first item's note will be migrated to the extra field, but the storage setting will still stay on note because the migration didn't work
    a. Deleting the corrupt note and trying to migrate again will succeed
    b. But then migrating back to note will result in 2 citation notes for the item, and usually and error if I try and click on one
  4. With rethrowing the error, the failed transaction seems to have no effect - after deleting the corrupt note everything starts working again

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Oct 23, 2022

Thanks for the proposed fix, I've added a comment on that.

Meanwhile I've also been doing some investigation and found that the transaction is actually getting rolled back correctly (at least in the database itself). If you restart Zotero after the failed migration, everything will be as it was before attempting the migration. So there seems to be some inconsistency between Zotero's in-memory representation of the item data and the actual database. Do you know if there is any caching layer or something similar that needs to be considered when running transactions that may roll back? I've been looking at some of the code in chrome/content/zotero/xpcom in the Zotero repo, but could not find the root cause of the problem yet...

@Dominic-DallOsto
Copy link
Collaborator

Hmm yeah, you're right. That's interesting. The only mention of a cache I've seen so far is here

A caching layer breaks the normal file-locking in SQLite that allows for safe concurrent file access

@Dominic-DallOsto
Copy link
Collaborator

This sounds like the same issue.

@RoBaaaT
Copy link
Contributor Author

RoBaaaT commented Oct 23, 2022

This sounds like the same issue.

Indeed, that seems to be the same issue. I'm wondering whether there is any way to trigger a full reload of Zotero's state from the database for use cases like ours.

Anyways, as a simple fix for our issue I've instead changed the migration to run in two steps (whereas previously it would load the data for an item and then immediately try to migrate it):

  1. Load citation data for all items
  2. Migrate citation data for all items

If any errors occur during step 1, the migration will abort before even making any changes to the items, which saves us from having to undo changes manually. Of course if errors occur during step 2, we are going to run into the same issue as before, but this should never happen.

In my testing this now seems to work as intended.

@Dominic-DallOsto
Copy link
Collaborator

Thanks! That sounds like a good workaround.

RoBaaaT and others added 14 commits October 26, 2022 20:49
This makes it so that the style of the preference
window is consistent with the rest of the Zotero
application. I was not able to figure out how to
achieve this with html.
This change makes migrating the storage location
for citation data atomic by running the migration
for all items in a Zotero DB transaction. If any
problems occur during the migration, the transaction
aborts and no changes are made to the items. In
this case the storage preference also remains un-
changed and the user is alerted about the failed
migration. The alert includes a list of item titles
that caused the migration to fail, so that the user
can at least manually try to fix the broken citation
data.
@Dominic-DallOsto
Copy link
Collaborator

Perfect, this works nicely for me now. And also after rebasing.

Thanks again for all the great work and sticking through the debugging process!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants