JDownloader Community - Appwork GmbH
 

Reply
 
Thread Tools Display Modes
  #281  
Old 06.02.2018, 12:14
Hartm
Guest
 
Posts: n/a
Default

hello,
i usually download with 50mbi/s but sometimes it goes down to 1000kb/s so i have to pause and resume the download.. is it possible to make a script for that , that it will every 30 seconds pause/resume the download?
Reply With Quote
  #282  
Old 06.02.2018, 12:51
Hartm
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by mgpai View Post
Code:
// Auto stop/restart downloads if the current average speed is below limit.
// Trigger Required: "Interval"

var minSpeed = 128; // (KiB/s) <- minimum average download Speed.
var minDuration = 0.3; // (minutes) <- minimum download duration per link.
var waitTime = 0.1; // (minutes) <- wait time before restart.

if (running() && getAverageSpeed() < minSpeed * 1024) {
    stopDownloads();
    sleep(waitTime * 60 * 1000);
    startDownloads();
}

// Check if all downloads have been running for atleast the minimum duration.
function running() {
    var links = getRunningDownloadLinks();
    if (links.length > 0) {
        for (i = 0; i < links.length; i++) {
            var link = links[i];
            if (link.getDownloadDuration() < minDuration * 60 * 1000) {
                return false;
            }
        }
        return true;
    } else {
        return false;
    }
}
unfortunately it doesnt work anymore? does it need to be updated? or am i doing something wrong?
Reply With Quote
  #283  
Old 06.02.2018, 13:14
Jiaz's Avatar
Jiaz Jiaz is offline
JD Manager
 
Join Date: Mar 2009
Location: Germany
Posts: 81,326
Default

@Hartm: what exactly doesnt work? there have been no changes to JDownloader and script.
__________________
JD-Dev & Server-Admin
Reply With Quote
  #284  
Old 07.02.2018, 00:22
neik
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by Jiaz View Post
@neik: you can copy/paste Settings-Advanced Settings, PackagizerSettings.rulelist
For eventscripter, EventScripter.scripts
Thanks Jiaz, the packagizer solved my problem. ;-)
Reply With Quote
  #285  
Old 07.02.2018, 01:05
DaDealer DaDealer is offline
Registered / Inactive
 
Join Date: Oct 2017
Posts: 112
Default

@hartm
Try this script

Trigger is Interval with 10000ms

Code:
//überprüfen, ob überhaupt gedownloadet wird
if (isDownloadControllerRunning() && !isDownloadControllerStopping()) {
    var running = getRunningDownloadLinks();
    //alle laufenden Downloads überprüfen
    for (var i = 0; i < running.length; i++) {
        //überprüfen, ob der Download mindestens seit 30 Sekunden läuft
        if (running[i].getDownloadDuration() > 20000) {
            //überprüfen, ob die Geschwindigkeit unter 500kb/s ist (habe 100.000er - dementsprechend an die eigene Leitung anpassen!)
            if (running[i].getSpeed() < 1000 * 1024) {
                //Reconnecten!
                requestReconnect();
            }

        }
    }
}
Reply With Quote
  #286  
Old 07.02.2018, 08:45
Hartm
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by DaDealer View Post
@hartm
Try this script

Trigger is Interval with 10000ms

Code:
//überprüfen, ob überhaupt gedownloadet wird
if (isDownloadControllerRunning() && !isDownloadControllerStopping()) {
    var running = getRunningDownloadLinks();
    //alle laufenden Downloads überprüfen
    for (var i = 0; i < running.length; i++) {
        //überprüfen, ob der Download mindestens seit 30 Sekunden läuft
        if (running[i].getDownloadDuration() > 20000) {
            //überprüfen, ob die Geschwindigkeit unter 500kb/s ist (habe 100.000er - dementsprechend an die eigene Leitung anpassen!)
            if (running[i].getSpeed() < 1000 * 1024) {
                //Reconnecten!
                requestReconnect();
            }

        }
    }
}
my downlaodrate dropps to 500kb/s and it should trigger the script right? But it doenst do anyhting.. the download just keeps going... also it would be nice if the download rate dropps under 1Mbi/s

in event scripter i enabled the script due download start is that wrong?

Last edited by Hartm; 07.02.2018 at 09:23.
Reply With Quote
  #287  
Old 07.02.2018, 10:39
Jiaz's Avatar
Jiaz Jiaz is offline
JD Manager
 
Join Date: Mar 2009
Location: Germany
Posts: 81,326
Default

@Hartm: Trigger must be set to 'Interval' mit 1000 ms interval.
__________________
JD-Dev & Server-Admin
Reply With Quote
  #288  
Old 07.02.2018, 14:11
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Quote:
Originally Posted by Hartm View Post
.. is it possible to make a script ... that it will every 30 seconds pause/resume the download?
Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/Hartm.js

Last edited by mgpai; 09.02.2018 at 06:11. Reason: Updated script location
Reply With Quote
  #289  
Old 07.02.2018, 18:24
netgearjd netgearjd is offline
Registered / Inactive
 
Join Date: Aug 2014
Posts: 92
Default

I was directed here by Jiaz from my feature request thread, so here's a copy-paste of what I'm looking to do:

-----

Here's an example to illustrate what I'm looking for. Say I have 500 or so links in the LinkGrabber or Downloads list. However I already have 200 of those files downloaded previously. Now it's pointless and a sheer waste of time, power, bandwidth etc. to re-download those 200 files, and it's obviously not feasible to manually look through the 500 and remove the 200.

Now suppose I have a simple text file containing a list of all the files I already have (could be in any location and on any internal or external media, but the list contains only file names and not paths).

What I want is a Subtract File List feature where I can provide the file list to JD, and it will automatically mark (say with red or yellow background) all the links that match the names of files I already have. There should also be a new menu option (along with Delete Links: disabled/failed/finished/offline) i.e. Delete Links: duplicates, so that one can quickly and easily get rid of all the matching links after reviewing them.

The matching links can of course be directly removed from the LinkGrabber or Downloads list too, but highlighting them with a different color will enable users to review which ones they really want to delete. For example a link may exactly match the name of a pre-existing file, but the user may decide to download anyway because the files are different.

-----

So, is this something that can be scripted?
Reply With Quote
  #290  
Old 08.02.2018, 07:20
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Quote:
Originally Posted by netgearjd View Post
... What I want is a Subtract File List feature where I can provide the file list to JD, and it will automatically mark (say with red or yellow background) all the links that match the names of files I already have. There should also be a new menu option (along with Delete Links: disabled/failed/finished/offline) i.e. Delete Links: duplicates, so that one can quickly and easily get rid of all the matching links after reviewing them ...
The option to set foreground/background color to the matching links is not available in the script environment. However, it is possible to remove/rename/disable them. It might also be possible (new API method required) to set comment (e.g. "Duplicate File") to the matching links. Of these methods, disabling the links might be the most convenient, as they can then be easily removed using "Delete Links: disabled" option.

Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/netgearjd.js

Last edited by mgpai; 09.02.2018 at 06:10. Reason: Updated script location
Reply With Quote
  #291  
Old 08.02.2018, 11:04
Jiaz's Avatar
Jiaz Jiaz is offline
JD Manager
 
Join Date: Mar 2009
Location: Germany
Posts: 81,326
Default

@mgpai: thanks for your help and support!
__________________
JD-Dev & Server-Admin
Reply With Quote
  #292  
Old 08.02.2018, 22:33
Hartm
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by mgpai View Post
Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/requests/Hartm.js
thanks for that =)
but i dont think it is working? my download goes 65 seconds with 885kbi/s and it doenst reconnect...
Reply With Quote
  #293  
Old 09.02.2018, 06:09
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

@Jiaz: Always my pleasure

Quote:
Originally Posted by Hartm View Post
... is it possible to make a script ... that it will every 30 seconds pause/resume the download?
Quote:
Originally Posted by Hartm View Post
... my download goes 65 seconds with 885kbi/s and it doenst reconnect...
The script does not 'reconnect', it checks the download speed between specified intervals and pauses/resumes the downloads if it is below target speed, which I believe is as per your original request.

If that is still what you are looking for, please make sure you have selected 'interval' as trigger and set it to '60000'. For testing purposes you can set a very high target speed (e.g. 1024000) and see if the script is being triggered. You can visually confirm it by watching the pause button in GUI. If the script is working correctly, you should be able to see it being disabled/enabled for the duration specified in the script.

Note: The script has bee moved to:
Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/Hartm.js
Reply With Quote
  #294  
Old 09.02.2018, 10:28
DaDealer DaDealer is offline
Registered / Inactive
 
Join Date: Oct 2017
Posts: 112
Default

Hi,
i'm searching a script for automatic update. the last one i got is not working.
Reply With Quote
  #295  
Old 09.02.2018, 11:09
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Quote:
Originally Posted by DaDealer View Post
... i'm searching a script for automatic update. the last one i got is not working.
Restart and update when Idle? Which script did you try?
Reply With Quote
  #296  
Old 09.02.2018, 14:26
DaDealer DaDealer is offline
Registered / Inactive
 
Join Date: Oct 2017
Posts: 112
Default

i got one that was checking every 8 hours if there is an update or not. when theres was one, JD ask everytime time if it is ok to update. i need one that is not asking.
Reply With Quote
  #297  
Old 09.02.2018, 15:05
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Quote:
Originally Posted by DaDealer View Post
i got one that was checking every 8 hours if there is an update or not. when theres was one, JD ask everytime time if it is ok to update. i need one that is not asking.
Have you tried this script? Here is a newer version, which includes an additional 'linkcollector' check. To execute the script every 8 hours, set the 'Interval' to '28800000'.

Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/DaDealer.js

We can also check/modify your existing script, if you post it here. If you have a different solution in mind, feel free to suggest it.
Reply With Quote
  #298  
Old 09.02.2018, 20:28
DaDealer DaDealer is offline
Registered / Inactive
 
Join Date: Oct 2017
Posts: 112
Default

the script was:

Code:
// Check if updates are availaible when JD is idle
if (callAPI("update", "isUpdateAvailable") && isDownloadControllerIdle()) {
    // Restart JD and Update
    callAPI("update", "restartAndUpdate")
}
i try the new one. we will see if it works or not. thank you mgpai
Reply With Quote
  #299  
Old 09.02.2018, 22:45
Hartm
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by mgpai View Post
@Jiaz: Always my pleasure





The script does not 'reconnect', it checks the download speed between specified intervals and pauses/resumes the downloads if it is below target speed, which I believe is as per your original request.

If that is still what you are looking for, please make sure you have selected 'interval' as trigger and set it to '60000'. For testing purposes you can set a very high target speed (e.g. 1024000) and see if the script is being triggered. You can visually confirm it by watching the pause button in GUI. If the script is working correctly, you should be able to see it being disabled/enabled for the duration specified in the script.

Note: The script has bee moved to:
Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/Hartm.js

yes sorry it works.. i didnt see that because i mean something different.. i mean stop and go...

i have to completely stop the download and then start it again to regain fullspeed....

do i have to change setDownloadsPaused to setDownloadsStart ?
Reply With Quote
  #300  
Old 10.02.2018, 08:45
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Quote:
Originally Posted by Hartm View Post
... i have to completely stop the download and then start it again to regain fullspeed....

do i have to change setDownloadsPaused to setDownloadsStart ?
If a download is fully stopped, an additional check to verify the download duration is required to ensure sufficient time is given to reach its normal speed again.

Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/Hartm_2.js
Reply With Quote
  #301  
Old 10.02.2018, 20:21
RPH
Guest
 
Posts: n/a
Question

Hi, I am running a Pi2 with Ubuntu Mate 16.04 and JDownloader headless. How can I go about making the following work using event scripter:

Event: when download controller starts
Code:
*if files exist in folder /home/myuser/myfolder*
then "killall transmission-gtk" #This is a Linux command normally run in terminal
*end*
Event: when download starts
Code:
"killall transmission-gtk"
Event: when download controller stops
Code:
call home/myuser/myscript.sh
"transmission-gtk %U -m" #must only run after myscript.sh has finished
The contents of myscript.sh is as follows:
Code:
#!/bin/bash

for i in /home/myuser/myfolder/*.mp4
do
/usr/local/bin/gdrive upload --delete "$i" #uploads file to google drive and then deletes it from disk
done
Any help is appreciated, thanks !
Reply With Quote
  #302  
Old 11.02.2018, 08:52
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Something like this should work. Jiaz should be able to confirm.

Event: when download controller starts
Code:
var myFolder = "/home/myuser/myfolder";
var fileExists = getPath(myFolder).getChildren().length;
if (fileExists) callAsync(null, "killall", "transmission-gtk");

Event: when download starts
Code:
callAsync(null, "killall", "transmission-gtk");

Event: when download controller stops
Code:
var myScript = "home/myuser/myscript.sh";
callSync(myScipt);
callAsync(null, "transmission-gtk", "%U", "-m");
  • Install/test the scripts in a desktop install.
  • Copy/paste "Settings>Advanced Settings>EventScripter.scripts" contents to WebUI (headless install)
Reply With Quote
  #303  
Old 11.02.2018, 13:17
RPH
Guest
 
Posts: n/a
Question

Quote:
Originally Posted by mgpai View Post
Something like this should work. Jiaz should be able to confirm.
  • Install/test the scripts in a desktop install.
  • Copy/paste "Settings>Advanced Settings>EventScripter.scripts" contents to WebUI (headless install)
Thank-you very much ! I will test it and let you know.

Quick question, is there any difference in running the "transmission-gtk" commands Synchronous or Asynchronous ? And all the event scripts should be set as Synchronous ?

EDIT: Also is it possible to update and restart Jdownloader at a certain time of the day if and only if updates are available ? I noticed that you set a "start time" on page 1 and used the interval trigger.

Last edited by RPH; 11.02.2018 at 13:53.
Reply With Quote
  #304  
Old 11.02.2018, 16:34
Hartm
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by mgpai View Post
If a download is fully stopped, an additional check to verify the download duration is required to ensure sufficient time is given to reach its normal speed again.

Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/Hartm_2.js
thank you very much works like a charm =)
Reply With Quote
  #305  
Old 11.02.2018, 20:45
RPH
Guest
 
Posts: n/a
Question

Based on my earlier question about updating & restarting JDownloader at a specific time of the day if an update is available, I wrote this script:

Code:
var t = [03, 45]; //Set Starting Time 

if (isDownloadControllerIdle() && isUpdateAvailable()) {
    interval = 1000;
    restartAndUpdate();
} else {
    var timeDiff = (new Date().setHours(t[0], t[1])) - (new Date());
    if (timeDiff <= 0) {
        interval = (86400000) - Math.abs(timeDiff);
    } else {
        interval = timeDiff;
    }
}

//Functions

function isUpdateAvailable() {
    return callAPI("update", "isUpdateAvailable");
}

function restartAndUpdate() {
    callAPI("update", "restartAndUpdate");
}
However, when the current time is after the starting time it doesn't work. For some reason the "if" statement will not evaluate the negative resulting number from the modulus.

I didn't want to have the interval running every second or every minute until the starting time....

EDIT: I changed the code to not use the modulus and it seems to be working fine now. But how can I check if another script is running ??? I don't want the update to run if my "Event: when download controller stops" script is running.

Last edited by RPH; 12.02.2018 at 17:32. Reason: Corrected script.
Reply With Quote
  #306  
Old 12.02.2018, 01:40
netgearjd netgearjd is offline
Registered / Inactive
 
Join Date: Aug 2014
Posts: 92
Default

First of all, thanks a lot for the script. Simple, yet 100% effective.

Quote:
Originally Posted by mgpai View Post
It might also be possible (new API method required) to set comment (e.g. "Duplicate File") to the matching links. Of these methods, disabling the links might be the most convenient, as they can then be easily removed using "Delete Links: disabled" option.
I would prefer setting the comment field actually, since I have links in other packages enabled/disabled as per my requirement and I don't see how "Delete Links: disabled" can be restricted only to a particular package.

@Jiaz: Can we have a new API method to set the link comment from a script?

@mgpai: As for the script itself, I want to make one small improvement if possible - how can I add a check to see whether the file exists or not before it is read, and display a simple warning dialog and abort execution if it doesn't exist?
Reply With Quote
  #307  
Old 13.02.2018, 07:33
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Quote:
Originally Posted by RPH View Post
... Quick question, is there any difference in running the "transmission-gtk" commands Synchronous or Asynchronous ? And all the event scripts should be set as Synchronous ?...
Use callSync() to call an external process and wait for the process to return (end) before executing the next line in the code.

Enable the "Synchronous Execution" in a script, to wait for the current instance of the script to end, before executing subsequent instance(s) of the same script, if/when triggered.
Reply With Quote
  #308  
Old 13.02.2018, 07:41
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Quote:
Originally Posted by netgearjd View Post
... add a check to see whether the file exists or not before it is read, and display a simple warning dialog and abort execution if it doesn't exist?
Script Updated:
Code:
github.com/mgpai/resources/blob/master/jdownloader/eventscripter/scripts/netgearjd.js

Last edited by mgpai; 13.02.2018 at 07:41. Reason: Made link to the script visible
Reply With Quote
  #309  
Old 13.02.2018, 11:09
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

Quote:
Originally Posted by RPH View Post
... how can I check if another script is running ??? I don't want the update to run if my "Event: when download controller stops" script is running.
Use setProperty() to set a global property in your "Event: when download controller stops" script to indicate that it is running and use getProperty() in your update script to access/check that property before restarting to update.
Reply With Quote
  #310  
Old 13.02.2018, 15:13
RPH
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by mgpai View Post
Use callSync() to call an external process and wait for the process to return (end) before executing the next line in the code.

Enable the "Synchronous Execution" in a script, to wait for the current instance of the script to end, before executing subsequent instance(s) of the same script, if/when triggered.
Quote:
Originally Posted by mgpai View Post
Use setProperty() to set a global property in your "Event: when download controller stops" script to indicate that it is running and use getProperty() in your update script to access/check that property before restarting to update.
Alright, thanks !
Reply With Quote
  #311  
Old 13.02.2018, 18:50
Jiaz's Avatar
Jiaz Jiaz is offline
JD Manager
 
Join Date: Mar 2009
Location: Germany
Posts: 81,326
Default

@mgpai: Thanks for providing great support here !

@RPH: mgpai will be great eventscript teacher for you be nice and you will become master like him
__________________
JD-Dev & Server-Admin
Reply With Quote
  #312  
Old 16.02.2018, 13:51
RPH
Guest
 
Posts: n/a
Default

Hi guys, I got a big problem. While testing my scripts, I set the "updateAndRestart" command to run if JDownloader is idle with the interval as 1000ms. Now as soon as JDownloader starts, it restarts and I cannot use it.

How can I disable this ? Thanks
Reply With Quote
  #313  
Old 16.02.2018, 14:09
mgpai mgpai is offline
Script Master
 
Join Date: Sep 2013
Posts: 1,636
Default

@RPH: You can disable the script by editing "org.jdownloader.extensions.eventscripter.EventScripterExtension.scripts.json" which can be found in 'cfg' folder.
Reply With Quote
  #314  
Old 16.02.2018, 14:13
Jiaz's Avatar
Jiaz Jiaz is offline
JD Manager
 
Join Date: Mar 2009
Location: Germany
Posts: 81,326
Default

In your cfg folder you will find org.jdownloader.extensions.eventscripter.EventScripterExtension.scripts.json
either remove it or edit and search enabled and set to false
__________________
JD-Dev & Server-Admin
Reply With Quote
  #315  
Old 16.02.2018, 14:16
RPH
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by mgpai View Post
@RPH: You can disable the script by editing "org.jdownloader.extensions.eventscripter.EventScripterExtension.scripts.json" which can be found in 'cfg' folder.
Thanks ! The restart and update command kept asking me for permission so I was trying to force it to run so I could give it permission and set it to never ask again. I removed the update check in the "if" statement but completely forgot to change the interval from 1s.

Once I have given it permission it will not ask for it again, correct ? Even if JDownloader shuts down and turns on again with say a power outage ? Because I am sure I have given it permissions before but it still asks.

Last edited by RPH; 16.02.2018 at 14:31.
Reply With Quote
  #316  
Old 16.02.2018, 14:38
Jiaz's Avatar
Jiaz Jiaz is offline
JD Manager
 
Join Date: Mar 2009
Location: Germany
Posts: 81,326
Default

Ah, its about permission. This one is saved in JDownloader. Yes, the permission is saved and not asked again. Permissions are on per method basis
__________________
JD-Dev & Server-Admin

Last edited by Jiaz; 16.02.2018 at 14:46.
Reply With Quote
  #317  
Old 16.02.2018, 14:54
RPH
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by Jiaz View Post
Ah, its about permission. This one is saved in JDownloader. Yes, the permission is saved and not asked again. Permissions are on per method basis
It seems though like every time I change this block of code it asks for permission again:

Code:
if (isDownloadControllerIdle() && isUpdateAvailable()) {
    interval = 1000;
    restartAndUpdate();
}
Is there a config file where I can just manually set the permission to allowed or check if it is allowed ?

Last edited by RPH; 16.02.2018 at 15:24.
Reply With Quote
  #318  
Old 16.02.2018, 16:49
Jiaz's Avatar
Jiaz Jiaz is offline
JD Manager
 
Join Date: Mar 2009
Location: Germany
Posts: 81,326
Default

@RPH: I just checked, permissions are stored for that script. when you change it, permissions are lost
__________________
JD-Dev & Server-Admin
Reply With Quote
  #319  
Old 16.02.2018, 17:00
RPH
Guest
 
Posts: n/a
Default

Quote:
Originally Posted by Jiaz View Post
@RPH: I just checked, permissions are stored for that script. when you change it, permissions are lost
Thanks for checking. So you mean if any line of code is changed in the script, all permissions for that script are lost ?

How would I go about allowing permissions for my "update check" then, because it is set to run in the early hours of the morning and only when an update is available ? It's thus not possible for me to sit and wait for the permission dialog box to appear on myJDownloader.
Reply With Quote
  #320  
Old 16.02.2018, 17:05
Jiaz's Avatar
Jiaz Jiaz is offline
JD Manager
 
Join Date: Mar 2009
Location: Germany
Posts: 81,326
Default

I will add easy method to disable permission checks
__________________
JD-Dev & Server-Admin
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

All times are GMT +2. The time now is 03:50.
Provided By AppWork GmbH | Privacy | Imprint
Parts of the Design are used from Kirsch designed by Andrew & Austin
Powered by vBulletin® Version 3.8.10 Beta 1
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.