himselfv / wakan

Japanese and Chinese learning tool with dictionary
38 stars 7 forks source link

Dependencies in Component Downloader #252

Open himselfv opened 10 years ago

himselfv commented 10 years ago

Original report by me.

Originally reported on Google Code with ID 252

Some components may require other components to function. For instance:
- dictionary import requires wordfreq_ck (it may be outdated but it shouldn't be missing)
- kanjidic import (in present form) requires unihan and radicals.txt

Perhaps there's a need to implement component dependencies:

  [child]
  Requires=parent1,parent2

Then every time we download child for any reason, both parents shall be downloaded.

This needs to be thought through, a decision is made what strategy to employ with dependencies
(see comments) and then it implemented.

Reported by himselfv on 2014-06-05 15:50:34

himselfv commented 10 years ago

First idea:

[child] Requires=parent1,parent2

And every time we download child for any reason, both parents shall be downloaded.

Immediate doubts:

  1. Do we just download missing parents, or update too? What if the user did not want to update the parent? Perhaps just download missing then (unless checked explicitly). So there needs to be a "state" for downloads: "Disabled, Download if missing, Forced download"
  2. We usually import stuff after downloading, and import may already require dependencies. So download list needs to be sorted according to dependency rules beforehand.

Second idea: Perhaps we don't exactly need a broad dependency system, but just something like

Require('missing-file.txt');

At any time in the program. Then Doubt 1 is automatically covered (if the file is there then it's there). Doubt 2 too (we check for it when we need it).

Doubts here:

  1. What if we need "anything from this group" (for ex. any version of kanjidic to import unihan)? Maybe we can pop up a window asking the user to choose at least one (of filtered list).
  2. This breaks the idea of "select first, download all later" in the downloader. Some items will be downloaded in order, others inline when importing other items. In this scenario this probably cannot be helped. We can only try to minimize the number of times we really need something immediately when downloading other stuff.

How to minimize that?

  1. Do not rely on other components immediately. E.g. kanjidic import: do not actually import it immediately. Just download several kanjidics and several (say) unihans which are parsed completely independently. Then have a place where the user can switch between the versions. There, if there are no versions of something, the user is presented with the standard "RequireAny(type=unihan)".
  2. Ship all required components with the app. There's no reason not to. Don't make life difficult, just assume the files are present. We have all rights to crash and burn if the user deleted some files which came with the app. We're not a Chip & Dale rescue squad for corrupted installations. But, are there really no files which may be required for some optional components, but are of wide enough use that they can't just be shipped with that component?

More considerations:

  1. It'd also be nice to be able to do

    //You seem to have no Japanese fonts installed, go download some fonts OpenDownloads(type=font) // RequireSome(type=font)

    //DownloadMoreRomajiButtonClick() OpenDownloads(type=romaji)

    //You have no dictionaries! No kanji data! RequireSome(type=dic & base-language=jp) RequireSome(type=kanjidic)

  2. Since the downloader also handles updates, it'd be nice to have it update all components, including those which were shipped with the app. How to implement that? Maybe just download the "app package" which includes all components, even those which weren't changed? Or download only those components which were changed?

  3. If latter, this almost automatically makes us Chip & Dale after all, because we can just stick Require('component-name') and re-download it if missing.

  4. If latter, maybe hide or group all those "ship-with-app" components in the downloader? We can't hide them completely, what if the user wants to uncheck them to stop from updating? But we don't want spamming the download window with stuff no one understands or needs to care about. Maybe there should be a special type of download called "Core components" which isn't shown at all, and there's a special setting "Auto-update the app" which handles whether all of that stuff is updated?

In that case we should skip this if we're in type=[whatever] mode. But perhaps also when we're in free mode. I just wanted to download some stuff, why is my Wakan updating? So perhaps those components need only to be updated at the start of the app, if so configured (together with everything else configured to auto-update, but before everything else. Perhaps there needs to be a separate option page 'Auto-updating'?).

So for now the resolution is as such:

  1. Ship all required components with the app, and assume everything basic is there. Do not do anything to amend for that, just tell the user to go redownload/"update" the app (this will download all basic components).
  2. Design everything so that all alternative components are downloaded and converted separately, and then you can choose which to merge with which (and are pointed to downloader if there's none of something).
  3. Update all basic components separately, but mark all of them as "core" and hide from the manual downloader.

I've not decided yet how auto-update will work, perhaps it will be working in the background, then it'd be something like "download core to temp dir; if there were core updates, stop downloading until restart + nudge user. If no core updates, then download the rest of the components and import all" or maybe "and plan to import on next restart" just like with core.