Before asking for help please read "Requesting Help and Suggestions" by clicking on that tab above here.
  • Page:
  • 1

TOPIC:

Automatically download GEDCOM file 3 weeks 3 days ago #1

  • Jefferson49
  • Jefferson49's Avatar Topic Author
  • Offline
  • New Member
  • New Member
  • Posts: 20
In order to transfer data from my main webtrees database to other programs, it would be helpful to automatically download GEDCOM files from webtrees without user interaction in the browser.
Is there some possibility available?

With the positive experience in mind about my first middleware module from this topic , I have the following draft idea:

  • Create a batch file to call a browser with a certain URL, e.g. c:\programs\browser.exe http://webtrees_side/index.php?route...&downloadGedcom=user
  • Write a middleware module, which will catch the "downloadGedcom" URL parameter
  • Call a function from the middleware module to download the GEDCOM file with certain user rights

public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$params = $request->getQueryParams();
$access_level = $params ?? '';

if ($access_level !== '') {
this->gedcom_download_function(tree, ..., access_level)
}

return $handler->handle($request)
}


Would that be a feasible approach?

If yes: how would the function call for the GEDCOM download look like?

Please Log in or Create an account to join the conversation.

Automatically download GEDCOM file 3 weeks 2 days ago #2

  • fisharebest
  • fisharebest's Avatar
  • Offline
  • Administrator
  • Administrator
  • Posts: 15173
There is already a URL for downloading GEDCOM files. Just go to the control panel, and click the download link for a tree.

> Create a batch file to call a browser with a certain URL

The problem you have is that your batch-file will not be authenticated, and so you'll get a 403 (access denied) response.

> Write a middleware module, which will catch the "downloadGedcom" URL parameter

Middleware are "wrappers" around every request. What you want is a new URL with a new "request handler" to process it.

Instead, I would create a module which registers a new URL, and provides code to handle it.

Look at ExportGedcomClient to see how the existing download GEDCOM script works.
You can simplify this a lot, by hard-coding the options and not including media or zipping the file.

Look at any of the existing chart modules to see how they register a new URL.
Remember that a module can declare itself to be a RequestHandler instead of a Middleware

But authentication remains a problem. You could do something like only accept requests from a specific IP address.
Greg Roach - This email address is being protected from spambots. You need JavaScript enabled to view it. - fisharebest.webtrees.net

Please Log in or Create an account to join the conversation.

Automatically download GEDCOM file 3 weeks 2 days ago #3

  • Jefferson49
  • Jefferson49's Avatar Topic Author
  • Offline
  • New Member
  • New Member
  • Posts: 20
Thank you very much for the detailed answer. I have already looked at the ExportGedcomClient. This code seems to be understandable to me.

About Authentification: I only want to use this in my private network.
Will webtrees reject a response if no user with the adequate rights is logged in?
Or, is it just very ugly to write an unprotected service to provide open access to the Gedcom file?

With the authentification in mind, I am thinking about a different approach:
Maybe, the Gedcom file could be saved to the data folder every time a user logs out. This would require to get a hook within the log-out procedure. The export code (from the ExportGedcomClient) would probably look the same.

I found a Logout class in \app\Http\RequestHandlers\Logout.php. Would it be feasible to write a wrapper around this class?

Please Log in or Create an account to join the conversation.

Automatically download GEDCOM file 3 weeks 2 days ago #4

  • fisharebest
  • fisharebest's Avatar
  • Offline
  • Administrator
  • Administrator
  • Posts: 15173
> About Authentification: I only want to use this in my private network.

Authentication is handled by the router (link URLs to request handlers).

Look in app/Http/Routes/Web.php

Some routes have a "is-an-admin" middleware.
Some routes have a "is-a-manager" middleware.
etc.

So, you can simply add a route without any authentication middleware, and it will be accessible without authentication.

In fact, you could add a new route (i.e. a new URL) to the *existing* request-handler.
Greg Roach - This email address is being protected from spambots. You need JavaScript enabled to view it. - fisharebest.webtrees.net

Please Log in or Create an account to join the conversation.

Automatically download GEDCOM file 3 weeks 2 days ago #5

  • Jefferson49
  • Jefferson49's Avatar Topic Author
  • Offline
  • New Member
  • New Member
  • Posts: 20
As a first step, I included the code from the ExportGedcomClient into my already existing middleware module. Most of the coding was easy, but it took me some time to recognize, where to get the GedcomExportService from. However, it seems that I can simply create a new one:

$gedcom_export_service = new GedcomExportService();
$gedcom_export_service->export($tree, $resource, true, $encoding, $access_level, $media_path);

Now, it already works fine. I can download Gedcom files by using certain parameters in the URL, i.e. "http://../webtrees/index.php?route=%2Fwebtrees%2Ftree%2Fhemprich&downloadgedcom=.my_gedcom". This also works without user login etc.

For the moment, I am already very happy: Maybe in a future step, I will work on further improvements with a specific module and registered URL, route etc.

Thanx again for the extraordinary support!

Please Log in or Create an account to join the conversation.

Automatically download GEDCOM file 2 weeks 4 days ago #6

  • Jefferson49
  • Jefferson49's Avatar Topic Author
  • Offline
  • New Member
  • New Member
  • Posts: 20
After successful testing my newly created webtrees middleware module, I provided the module code on GitHub:

DownloadGedcomWithURL
github.com/Jefferson49/DownloadGedcomWithURL

Please Log in or Create an account to join the conversation.

Automatically download GEDCOM file 2 weeks 3 days ago #7

  • fisharebest
  • fisharebest's Avatar
  • Offline
  • Administrator
  • Administrator
  • Posts: 15173
"Middleware" is really the wrong tool for this job.

There is a much simpler way to do this.

Create a module.
Create a function: getDownLoadGedcomAction();
Put your code in this function.

This function will be called you use use the URL /module/MODULE_NAME/DownLoadGedcom/TREE_NAME
Greg Roach - This email address is being protected from spambots. You need JavaScript enabled to view it. - fisharebest.webtrees.net

Please Log in or Create an account to join the conversation.

Automatically download GEDCOM file 2 weeks 2 days ago #8

  • Jefferson49
  • Jefferson49's Avatar Topic Author
  • Offline
  • New Member
  • New Member
  • Posts: 20
Well, I understand your point and I tried to create a module like in your explanation. However, I was facing several issues, which I could not get resolved:

How exactly to call the function by URL?
To get started, I tried to write a simple module "mymodule" with a function getMyTestAction() but could not call the function with an URL.
Following your explanation and with base_url="http://127.0.0.1/webtrees" and leaving out "get" and "Action" it should be:
http://127.0.0.1/webtrees/module/mymodule/MyTest
I have also tried several other versions without success.

How to call a function with several arguments?
In my case, I need three arguments:
public function getDownLoadGedcomAction(int $tree_id, string $access_level_requested, string $download_filename)
How would I call this with an URL, e.g. attach all arguments at the end?
http://127.0.0.1/webtrees/module/mymodule/DownLoadGedcom/1/visitor/filename

How to get a handle on the tree object?
I found a TreeService class, which provides a find method for a tree id. This seems to be a feasible approach.
$tree_service = new TreeService();
$tree = $tree_service->find($tree_id);

How to create the response?
In my earlier middleware module, a Response was created and returned as a ResponseInterface. In the newly created function in the module, I can not return this object. Probably, I need to directly forward the Response object to somewhere. However, I do not know which structure to call.
$response_factory = app(ResponseFactoryInterface::class);
return $response_factory->createResponse()

Please Log in or Create an account to join the conversation.

Do you need a web hosting solution for your webtrees site?
If you prefer a host that specialises in webtrees, the following page lists some suppliers able to provide one for you: 

Automatically download GEDCOM file 2 weeks 1 day ago #9

  • fisharebest
  • fisharebest's Avatar
  • Offline
  • Administrator
  • Administrator
  • Posts: 15173
> How would I call this with an URL, e.g. attach all arguments at the end?
?arg1=foo&arg2=bar&arg3=baz

In your code, you access them using
$params = $request->getQueryParams();
$arg1 = $params['arg1'] ?? 'default value for arg1';
$arg2 = $params['arg2'] ?? 'default value for arg2';
$arg3 = $params['arg3'] ?? 'default value for arg3';

> How to get a handle on the tree object?

The tree name is part of the URL, and so you can access it directly
$tree = $request->getAttribute('tree');
if ($tree === null) {
  throw new HttpBadRequestException('Tree parameter missing in URL');
}

> How to create the response?

To create a download response containing a GEDCOM file, copy the existing code:

github.com/fisharebest/webtrees/blob/mai...portGedcomClient.php
Greg Roach - This email address is being protected from spambots. You need JavaScript enabled to view it. - fisharebest.webtrees.net

Please Log in or Create an account to join the conversation.

  • Page:
  • 1
Powered by Kunena Forum