From 9252c883d4e12349838705cdd131a0d81f6ffdd3 Mon Sep 17 00:00:00 2001 From: Philip Sargent Date: Mon, 12 Apr 2021 23:07:38 +0100 Subject: [PATCH] JSON export documenation --- handbook/troggle/exportjson.html | 39 ++++++++++++++++++++++++ handbook/troggle/exporttgz.html | 28 +++++++++++++++++ handbook/troggle/json-cmd.jpg | Bin 0 -> 47600 bytes handbook/troggle/trog2030.html | 50 ++++++++++++++++++++++++------- handbook/troggle/trogindex.html | 10 +++++-- handbook/troggle/trogintro.html | 1 + handbook/troggle/trogmanual.html | 12 ++++++++ 7 files changed, 127 insertions(+), 13 deletions(-) create mode 100644 handbook/troggle/exportjson.html create mode 100644 handbook/troggle/exporttgz.html create mode 100644 handbook/troggle/json-cmd.jpg diff --git a/handbook/troggle/exportjson.html b/handbook/troggle/exportjson.html new file mode 100644 index 000000000..48e7840ca --- /dev/null +++ b/handbook/troggle/exportjson.html @@ -0,0 +1,39 @@ + + + + +Handbook Troggle JSON + + + +

CUCC Expedition Handbook

+

Handbook Troggle JSON

+ +

+We can export cave and expo data with Django templates that generate JSON, which is what CUYC do (and we have access to their code). + +We already have a proof of principle JSON export API working at +expo.survex.com/api/expeditions_json and we also have +a text-format export as TSV (tab-separated values), which are like comma-separated values and similarly importable into spreadsheets. + + +

Expoadmin method

+ +

Log in as 'expoadmin' (password: 'beery:cavey') at /admin/login/ then look at the entries for any one of +the objects: Caves, Expeditions, People etc. + + + +

+In the top left-hand corner is a drop-down menu, 'export as json' is shown selected in the image. +Select one or more of the objects listed and press the 'Go' button next to the drop-down menu. A JSON-formatted file will be produced 'troggle-ouput.json' in the troggle installation directory (where the troggle code .git file is). +

There is also an 'export as XML' option. +

The code which adds this capability into the Troggle Administration control panel is in troggle/core/admin.py. +


+Go on to: Troggle architecture
+Return to: Troggle in 2025-2030
+Troggle index: +Index of all troggle documents
+
+ + diff --git a/handbook/troggle/exporttgz.html b/handbook/troggle/exporttgz.html new file mode 100644 index 000000000..84aafc345 --- /dev/null +++ b/handbook/troggle/exporttgz.html @@ -0,0 +1,28 @@ + + + + +Handbook all.tgz + + + +

CUCC Expedition Handbook

+

Handbook all.tgz

+ +

+The old Makefile was an integral part of the pre-troggle 'scripts + spreadsheets' era of +cave data management. These days most files are regenerated whenever a data import is done into troggle, not +on a daily basis using the cron-scheduled Makefile. + +

The all.tgz archive is not updated regularly, but if it is you wil find it in
+noinfo/all.tgz + + +


+Go on to: Troggle architecture
+Return to: Troggle in 2025-2030
+Troggle index: +Index of all troggle documents
+
+ + diff --git a/handbook/troggle/json-cmd.jpg b/handbook/troggle/json-cmd.jpg new file mode 100644 index 0000000000000000000000000000000000000000..182d10a430c43ec17f515acfa43952e1833f838d GIT binary patch literal 47600 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 literal 0 HcmV?d00001 diff --git a/handbook/troggle/trog2030.html b/handbook/troggle/trog2030.html index f29f28082..cc8f203a4 100644 --- a/handbook/troggle/trog2030.html +++ b/handbook/troggle/trog2030.html @@ -10,7 +10,7 @@

Troggle in 2025-2030

5-Year Plan

-

[Philip Sargent, 1 June 2020] +

[Philip Sargent, 1 June 2020. Async updates 14 April 2021]

  • I reckon django has at least another 4-5 years left as a very active project (~2025) and at least a decade or so as a well-maintained project.
  • I reckon python has another 10-20 years at least. @@ -23,7 +23,7 @@ there is such a lot going on we would create a large volume of software even if

    Option 2

    We keep the same architecture as now, and incrementally replace modules that use django/SQL with direct object storage of collections using pickle(), shelve() and json(). -Concurrency is not a problem as all data is read-only. +Concurrency is not a problem as all data is read-only (this is not entirely true - see below). We keep the url-rewriting and html-template things in django.[and migrate the unit-tests (a recent innovation) from django to be run stand-alone.]

    This means that the "django-ness" part of troggle becomes quite small. @@ -55,28 +55,56 @@ We should have a good look at modifying everything so that we do not read in ev

    Documentation is the key to keeping troggle in a state where someone can pick it up and do a useful week's work, e.g. extracting the parsed logbooks to use shelve() storage throughout instead of SQL. The next time someone like Radost comes along during the next 5 years we want to be able to use them effectively. -

    Things that could be a bit sticky

    -

    -New functionality: e.g. making the whole thing GIS-centric is a possibility. -A GIS db could make a lot of sense. Not in scope for this discussion. +

    Things that could be a bit sticky 1 - multi-user safety

    +

    Multi-user synchronous use could be a bit tricky without a solid multi-user database sitting behind the python code. So removing all the SQL database use may not be what we want to do after all. +

    Under all conceivable circumstances we would continue to use WGSI or +ASGI to connect our python code to a user-facing +webserver (apache, nginx, gunicorn). Every time a webpage is served, it is done by a separate thread in the webserver and essentially a +new instance of Django is created to serve it. Django relies on its multi-user SQL database (MariaDB, postgresql) to ensure that competing +updates by two instantiations of itself to the same stored object are correctly atomic. But even today, if two people try to update the +same handbook webpage, or the same survex file, at the same time we expect horrible corruption of the data. Even today, +with the SQL database, writing files is not coded in a properly multi-user manner. We should write some file lock/serializer code +to make this safe. + +

    The move by Django +from single-threaded WSGI to asynchronous ASGI began with v3.0 and for 'views' almost complete in 3.2. +This makes the server more responsive, +but doesn't really change anything from the perspective of our need to stop users overwriting each others' work. If we just store +everything in in-memory dictionaries we may need to write our own asyncio python to do that synchronization. That would be a Bad Thing as +we are trying to make future maintenance easier, not harder. + +

    Things that could be a bit sticky 2 - front-end code

    There is not yet a front-end (javascript) framework on the client, i.e. a phone app or webpage, which is stable enough for us to commit effort to. Bits of troggle use very old jQuery ("edit this page", and the svx file editor) , and Flask looks interesting (but maybe is only simpler when starting a new project and doesn't scale to complexity the way Django does, but maybe in 2025 we -could see a good way to move all the user interface (rewritten to be GIS-centric) to the client +could see a good way to move all the user interface (rewritten to be GIS-centric?) to the client (re-written in Typescript -or Dart) and just have an API on the server. [We already have a proof of principle JSON export API working at -expo.survex.com/api/expeditions_json.] +or Dart) and just have an API on the server. [We already have a proof of principle JSON export API working, see +Troggle JSON.] +

    front-end code is not just a pretty face

    +

    Modern JavaScript frameworks support dynamic 'single-page websites' where all the component parts are fetched and replaced +asynchronously (this used to be called AJAX when it first appeared in +1999). This is fundamentally different from how Django was originally designed: using public URLs connected to code which produces a +complete webpage based on a single template. Django can interoperate + with dynamic systems but support will become increasingly baroque I imagine. + +

    Things that could be a bit sticky 3 - GIS

    +

    +New functionality: e.g. making the whole thing GIS-centric is a possibility. +A GIS db could make a lot of sense. Expo has GIS expertise and we have a lot of badly-integrated GPS data, so this needs a lot of thinking to be done and we should get on with that.

    API

    -

    We will also need an API now-ish, whatever we do, so that keen kids can write their own special-purpose front-ends using new cool toys. Which will keep them out of our hair. We can do this easily with Django templates that generate JSON, which is what CUYC do +

    We will also need an API now-ish, whatever we do, so that keen kids can write their own special-purpose front-ends using new cool toys. Which will keep them out of our hair. We can do this easily with Django templates that generate JSON, which is what CUYC do. We already have some of this: JSON export. +

    Postscript

    Andy Waddington, who wrote the first expo website in 1996, mentioned that he could never get the hang of Django at all, and working with SQL databases would require some serious book-revision:

    So a useful goal, I think, is to make 'troggle2' accessible to a generic python programmer with no specialist skills in any databases or frameworks. Put against that is the argument that that might double the volume of code to be maintained, which would be worse. Nevertheless, an aim to keep in mind. -But even 'just Python' is not that easy. Python is a much bigger language now than it used to be, with some esoteric corners. +But even 'just Python' is not that easy. Python is a much bigger language now than it used to be, with some increasingly esoteric corners, such as the new asyncio framework.. diff --git a/handbook/troggle/trogindex.html b/handbook/troggle/trogindex.html index 7a81bf47b..9f24335da 100644 --- a/handbook/troggle/trogindex.html +++ b/handbook/troggle/trogindex.html @@ -27,6 +27,9 @@

Troggle server configuration - how to get troggle running on a new machine (incoimplete!)
Troggle - Data Import - reset and import data
+ Troggle and Django - The Django web framework we use
Troggle: updating Django - Upgrading troggle to use a later Django version
Troggle unit tests - test suite for programmers
@@ -38,8 +41,11 @@ Archive Notes - old ideas and original discussions

Additional Scripts - non-django but important
-Additional Scripts - more detail
-QM (Question Mark) Scripts - all five ways we do it
+

diff --git a/handbook/troggle/trogintro.html b/handbook/troggle/trogintro.html index 0b34e108a..f81dac531 100644 --- a/handbook/troggle/trogintro.html +++ b/handbook/troggle/trogintro.html @@ -36,6 +36,7 @@ The troggle software is written and maintained by expo members.
  • expo.survex.com/survey_scans/ - List of all scanned original survey notes.
  • expo.survex.com/survey_scans/2018%252343/ - list of links to scanned notes for wallet #43 during the 2018 expo. +

    If you want to find out how to do something using troggle, then you may find it the troggle maintainers and advanced users manualTroggle - why we developed it diff --git a/handbook/troggle/trogmanual.html b/handbook/troggle/trogmanual.html index 3de8fd8e2..3c4cf167b 100644 --- a/handbook/troggle/trogmanual.html +++ b/handbook/troggle/trogmanual.html @@ -28,6 +28,18 @@

    Troggle is completely unlike any other django installation: it has a database, but the database is rebuilt from files every time it starts.

    Most of the data entry into troggle happens during or just after the expedition. +

    Advanced Users' Manual

    +

    We don't have one of these. You may find what you are looking for in Other scripts above. But there are a few things which are not really 'maintenance' and are not really cave data management either, e.g. +

    +but do scan + + +

    * "Troggle eats just one very big meal a year."