News:

Herr Otto Partz says you're all nothing but pipsqueaks!

Main Menu

Track information

Started by dreadnaut, August 20, 2021, 06:30:10 PM

Previous topic - Next topic

dreadnaut

Hello Cas and KyLiE,

I was considering re-adding the list of active races to the stunts.hu portal, at the very top. Would you be able to add something like the track.json on ZakStunts? It can be a file or a script as you prefer, as long as it outputs the same format.

This is how ZakStunts generates it:
Code (php) Select

    $current_track = Tracks::getCurrentTrack();

    $track_name = "{$current_track->name} - {$current_track->title}";
    $track_url  = "http://zak.stunts.hu/tracks/{$current_track->name}";
    $author     = $current_track->author;
    $deadline   = date('r', strtotime($current_track->end_date) + 86399);

    header('Content-Type: application/json');
    echo json_encode([
      'competition' => [
        'name'     => 'ZakStunts',
        'url'      => 'http://zak.stunts.hu',
      ],
      'track' => [
        'name'     => $track_name,
        'file'     => $track_url . '.trk',
        'url'      => $track_url,
        'deadline' => $deadline,
        'author'   => $author,
      ]
    ]);

KyLiE

I can't see why not.  I'll check with Cas as he is the one responsible for all the PHP code on Race For Kicks.

Cas

Hi!  Yes, that would be a very good thing to do. However, there's a catch. Even though so far Race For Kicks has been featuring only one active race all the time, it actually does not have a "current race", but an arbitrary number of "active races". It could theoretically feature more than one race at the same time with different starting and finishing dates. How would you like that to be represented?  In the future, at some point, it will happen that more than one race are running together. Additionally, while normally, a race name is the same as the track title, there is the ability for R4K to have an "event name", so that two different races on a same track have different names or a special event can be called for what it is, even if the track has another name (for example, "Race for Immortality" was an event raced on the track called "Bliss"). This is even more likely to happen in the future. What would you suggest us to do about that?  Cheers!
Earth is my country. Science is my religion.

dreadnaut

Those are very good points you make Cas, the format should be flexible enough to cater for multiple races and tracks. What about this:


{
  "website": {
    "name": "ZakStunts",
    "url": "http://zak.stunts.hu"
  },
  "races": [
    {
      "name": "ZCT242 - Full Fontal",
      "url": "http://zak.stunts.hu/tracks/ZCT242",
      "deadline": "Sat, 18 Sep 2021 23:59:59 +0200",
      "track": {
        "title": "Full Fontal",
        "author": "Overdrijf",
        "file": "http://zak.stunts.hu/tracks/ZCT242.trk"
      }
    },
    {
      ...
    }
  ]
}


races would be an array with all the active races. Name is the name of the race, and there's a separate track record for the track details, which could be optional.

Cas

#4
That looks good!  I'll make sure to add that to the code. It will take me a little bit because there's one thing it's currently doing in an untidy way that I've been wanting to change and I need to get that fixed before, but... maybe that's easier to fix than I expected and I could get all this working tonight.

Right now, I'm already working on R4K, adding a few security patches. The most important one is that R4K was storing passwords complete and as plain text. Unforgivable, I know!  But now that's fixed and passwords are going to be hashed. Of course, the directory was protected and inaccessible from outside the server anyway. So, now that I'm at it, I think I can add this in the same run :)

EDIT: OK... I *think* I did it. Please test it. Only thing I didn't know how to do was creating a nameless array that can be differentiated, so the race ID is used as an axis. You'll see what I mean when you parse the file. I'm sure it'll be no problem for you, but you'll certainly know the right way. Oops!  I'm unable to access the FTP, so I can't upload it. It looks like my IP changed again. I'll soon be uploading the changes!

ANOTHER EDIT: I forgot to mention that, once it's working, this information is saved to a file at http://www.raceforkicks.com/stunts-hu.api
Earth is my country. Science is my religion.

dreadnaut

Quote from: Cas on August 24, 2021, 03:54:03 AM
Only thing I didn't know how to do was creating a nameless array that can be differentiated, so the race ID is used as an axis. You'll see what I mean when you parse the file.

You can add elements without an index by... not using an index ;D


~$ php -a
php > $a = array();
php > $a[] = 77;
php > $a[] = 123;
php > echo json_encode($a);
[77,123]


Otherwise, you can remove the keys and keep only the values with array_values().


Regarding the name, maybe we can go for something generic like races.json ?

Cas

Oh!  It never occurred to me that it could be so simple!

The code is uploaded already and you can test the file, although I have not changed the name or the index yet

I would need to update the interface used for non-web integration (such as Bliss) via the tour.cfg file, as this one still can only show the last race and no event information. I haven't touched this file because I don't want to break compatibility with older versions of Bliss, so I'll have to think carefully of a way to do it. I don't want to use the json format for exchange outside the web, since it's very complex to parse and bugs become more likely. Within the web, you just use a pre-made function, so no problem.
Earth is my country. Science is my religion.

dreadnaut

Quote from: Cas on August 25, 2021, 02:30:34 PM
The code is uploaded already and you can test the file, although I have not changed the name or the index yet

Thank you! A couple of small things to fix:


  • Instead of website and url at top level, could you have title and url inside a website record? (see example above)
  • could you format deadline to include time and timezone? You can get a standard format with date('r', ...), which I can then parse using strtotime()
  • you have already mentioned the indexes :)

Cas

Alright... This is what happened:

  • I noticed what you pointed out about the website and URL, so I corrected it and now it's good
  • I changed the deadline format at first copying from your code, but that resulted in a -0300 timezone, which is strangely local in Argentina, yet the server is in Australia. Anyway, Race For Kicks turns the clock at midnight UTC, so I changed it to display "UTC". It's not exactly the same format you use, but you can easily convert it into what you need. Besides, I like it more this way, ha, ha. Just let me know
  • I thought I had understood the issue with the indices, but when I tried removing them, I didn't get what I expected, so I reverted to using indices again. I'll need a deeper explanation on the matter :P
  • I renamed the file to webapi-races.json. Now the extension agrees with the format. I wouldn't want to just use "races.json", as its simplicity suggests it's the standard way of retrieving race information from R4K while this is done through tour.cfg.
Attached is is what I got when I removed the indices. You surely can hint me on what I could be doing wrong. Each line, as displayed by the browser when the file is open directly, would get its own "index number" and all would be separated. This is a code snippet from the part that generates this:


$j["races"][$raceid]["url"] = "http://www.raceforkicks.com/index.php?page=race&race=" . $raceid;
$j["races"][$raceid]["deadline"] = $dl;

$j["races"][$raceid]["track"]["title"] = $md["Titl"];
$j["races"][$raceid]["track"]["author"] = $md["Autr"];
$j["races"][$raceid]["track"]["file"] = "http://www.raceforkicks.com/" . TRACKS . $race["track"] . ".trk";


For the version I attached, I had simply removed the "$raceid" from every line.
The file currently shows the version with the indices and the changes I described, if you want to test it!
Earth is my country. Science is my religion.

dreadnaut

The tricky bit is that every time you assign $a[] = ..., you add a new element to the array. So you need to prepare the record for the race, and add it in one operation. For example:


$record = [
  "url" => "http://www.raceforkicks.com/index.php?page=race&race={$raceid}",
  "deadline" => $dl,
  "track" => [
    "title" => $md["Titl"],
    "author" => $md["Autr"],
    "file" => "http://www.raceforkicks.com/" . TRACKS . $race["track"] . ".trk",
  ],
];

$j["races"][] = $record;


Regarding the timezone, maybe there's a different default timezone set? Try resetting it at the start of your PHP script:

date_default_timezone_set("UTC");


Note that you can also get more readable output with this option:

$text = json_encode($j, JSON_PRETTY_PRINT);

Cas

Ah!  Now I got you about the "un-indices" :D  I didn't know about the default time zone. I've been forcing it with gmdate(). And I'll have to try that JSON_PRETTY_PRINT to know what it is about. I suppose that won't change how the parser interprets the contents, right?
Earth is my country. Science is my religion.

dreadnaut

Quote from: Cas on August 26, 2021, 09:15:49 PM
I suppose that won't change how the parser interprets the contents, right?
It just adds whitespace to create indentation. It's good for reading and debugging, or if you don't care about how many characters you are using.

Cas

Alright!  I changed the code so now the index is undefined and it seems to work well!
Earth is my country. Science is my religion.

dreadnaut

Quote from: Cas on August 31, 2021, 01:23:24 AM
Alright!  I changed the code so now the index is undefined and it seems to work well!

Thanks Cas, I'll use it in the next days :)

dreadnaut

#14
I've got this working and I can load the races, no issues there. However, there was a flaw in my plan: retrieving the data can take some time, making the portal 3-4× slower to load. What if, instead of ZakStunts asking RaceForKicks about the current race, it worked the other way around?

Instead of calling to see what's the current race, I would add a script at, for example, stunts.hu/register-race, waiting for incoming requests. When you create a new race on RaceForKicks, you could send a POST request to that address, with the same data we have discussed above.

When the request arrives, I can verify that it comes from you, and store the information about the race in the database, and the will appear in the portal at the right time 8)   Bonus: we get a second archive of races: title, URL, dates, etc.

How does it sound? I can define this better if it seems doable to you.