From 089d0cebacb4e03adab91483216e107d11bb9dc0 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sat, 10 Jun 2023 13:39:41 +0600 Subject: [PATCH] several fixes and krontab migration --- docs/krontab/describing/krontabscheduler.md | 58 +++++++++ docs/krontab/describing/string-format.md | 117 ++++++++++++++++++ docs/krontab/introduction/faq.md | 19 +++ docs/krontab/introduction/how-to-use.md | 57 +++++++++ .../introduction/including-in-project.md | 35 ++++++ .../introduction/before-any-bot-project.md | 2 +- .../introduction/including-in-your-project.md | 4 +- docs/tgbotapi/introduction/proxy-setup.md | 2 +- .../logic/low-level-work-with-bots.md | 4 +- docs/tgbotapi/updates/heroku.md | 4 +- docs/tgbotapi/updates/long-polling.md | 8 +- docs/tgbotapi/updates/updates-filters.md | 6 +- docs/tgbotapi/updates/webhooks.md | 4 +- mkdocs.yml | 8 ++ 14 files changed, 311 insertions(+), 17 deletions(-) create mode 100644 docs/krontab/describing/krontabscheduler.md create mode 100644 docs/krontab/describing/string-format.md create mode 100644 docs/krontab/introduction/faq.md create mode 100644 docs/krontab/introduction/how-to-use.md create mode 100644 docs/krontab/introduction/including-in-project.md diff --git a/docs/krontab/describing/krontabscheduler.md b/docs/krontab/describing/krontabscheduler.md new file mode 100644 index 0000000..2315cac --- /dev/null +++ b/docs/krontab/describing/krontabscheduler.md @@ -0,0 +1,58 @@ +# KrontabScheduler + +`KronScheduler` is the simple interface with only one function `next`. This function optionally get as a parameter `DateTime` which will be used as start point for the calculation of next trigger time. This function will return the next `DateTime` when something must happen. + +### Default realisation + +Default realisation (`CronDateTimeScheduler`) can be created using several ways: + +* Via `buildSchedule` (or `createSimpleScheduler`) functions with crontab-like syntax parameter +* Via `buildSchedule` (or `SchedulerBuilder` object), which using lambda to configure scheduler + +In the examples below the result of created scheduler will be the same. + +#### Crontab-like way + +> NOTE: **Crontab-like syntax** +> See [String format](string-format.md) for more info about the crontab-line syntax + +This way will be very useful for cases when you need to configure something via external configuration (from file on startup or via some parameter from requests, for example): + +```kotlin +val schedule = "5 * * * *" +val scheduler = buildSchedule(schedule) + +scheduler.asFlow().onEach { + // this block will be called every minute at 5 seconds +}.launchIn(someCoroutineScope) +``` + +#### Lambda way + +In case of usage builder (lets call it `lambda way`), you will be able to configure scheduler in more type-safe way: + +```kotlin +val scheduler = buildSchedule { + seconds { + at(5) + } +} + +scheduler.asFlow().onEach { + // this block will be called every minute at 5 seconds +}.launchIn(someCoroutineScope) +``` + +### Custom scheduler + +You are always able to use your own realisation of scheduler. For example: + +```kotlin +class RandomScheduler : KronScheduler { + override suspend fun next(relatively: DateTime): DateTime { + return relatively + DateTimeSpan(seconds = Random.nextInt() % 60) + } +} +``` + +In the example above we have created `RandomScheduler`, which will return random next time in range `0-60` seconds since `relatively` argument. \ No newline at end of file diff --git a/docs/krontab/describing/string-format.md b/docs/krontab/describing/string-format.md new file mode 100644 index 0000000..b42a990 --- /dev/null +++ b/docs/krontab/describing/string-format.md @@ -0,0 +1,117 @@ +# String format + +As in `crontab` util, this library have almost the same format of string: + +| | Seconds | Minutes | Hours | Days of months | Months | Years | Timezone Offset | Week days | Milliseconds | +| --: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | +| Range | 0..59 | 0..59 | 0..23 | 0..30 | 0..11 | Any `Int` | Any `Int` | 0..6 | 0..999 | +| Suffix | - | - | - | - | - | - | `o` | `w` | `ms` | +| Optional | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ | +| [Full syntax](#bkmrk-supported-syntax) support | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | +| Position | 0 | 1 | 2 | 3 | 4 | Any after months | Any after months | Any after months | Any after months | +| Examples | `0`, `*/15`, `30` | `0`, `*/15`, `30` | `0`, `*/15`, `22` | `0`, `*/15`, `30` | `0`, `*/5`, `11` | `0`, `*/15`, `30` | `60o` (UTC+1) | `0w`, `*/2w`, `4w` | `0ms`, `*/150ms`, `300ms` | + +Example with almost same description: + +``` +/-------------------- (0-59) ············ Seconds +| /------------------ (0-59) ············ Minutes +| | /---------------- (0-23) ············ Hours +| | | /-------------- (0-30) ············ Days of months +| | | | /------------ (0-11) ············ Months +| | | | | /---------- (optional, any int) Year +| | | | | | /-------- (optional) ········ Timezone offset +| | | | | | | /----- (optional, 0-6) ··· Week days +| | | | | | | | /-- (optional, 0-999) · Milliseconds (0 by default) +* * * * * * 0o *w 0ms +``` + +Years, timezone, week days and milliseconds are optional settings. Next snippets are equal: + +``` +*/15 * * * * +*/15 * * * * * // with year +*/15 * * * * * 0ms // with year and milliseconds +``` + +### Supported syntax + +Currently the library support next syntax for date/time elements: + +* `{int}-{int}` - ranges +* `{int}/{int}` - start/step +* `*/{int}` - every {int} +* `{int}` - just at the time +* `{other_element},{other_element}` - listing +* `F` or `f` - first possible value +* `L` or `l` - last possible value (last day of month, for example) + +#### Ranges + +Ranges are working like common `rangeTo` (or `..`) in kotlin: + +``` +0-5 * * * * +``` + +In the example above scheduler will trigger every second from the beginning of the minute up to fifth second of minute. + +#### Start/Step + +Start/step is a little bit more complicated syntax. It means `start from the first element, repeat triggering every second element`. Examples: + +``` +5/15 * * * * +``` + +Means that each minute starting from fifth second it will repeat triggering every fifteenth second: `5, 20, 35, 50`. + +#### Every + +Every is more simple syntax and could be explained as a shortcut for `0/{int}`. Example: + +``` +*/15 * * * * +``` + +Means that each minute it will repeat triggering every fifteenth second: `0, 15, 30, 45`. + +#### Just at the time + +The most simple syntax. It means, that scheduler will call triggering every time when element was reached: + +``` +15 * * * * +``` + +Means that each minute scheduler will call triggering at the fifteenth second. + +#### Listing + +All the previous elements can be combined with listing. Lets just see several examples: + +``` +0,10 * * * * +``` + +Will trigger every minute at the `0` and `10` seconds (see [Just at the time](#just-at-the-time)) + +``` +0-5,10 * * * * +``` + +Will trigger every minute from `0` to `5` seconds and at the `10` seconds (see [Ranges](#ranges)) + +### Examples + +* `0/5 * * * *` for every five seconds triggering +* `0/5,L * * * *` for every five seconds triggering and on 59 second +* `0/15 30 * * *` for every 15th seconds in a half of each hour +* `0/15 30 * * * 500ms` for every 15th seconds in a half of each hour when milliseconds equal to 500 +* `1 2 3 F,4,L 5` for triggering in near first second of second minute of third hour of first, fifth and last days of may +* `1 2 3 F,4,L 5 60o` for triggering in near first second of second minute of third hour of first, fifth and last days of may with timezone UTC+01:00 +* `1 2 3 F,4,L 5 60o 0-2w` for triggering in near first second of second minute of third hour of first, fifth and last days of may in case if it will be in Sunday-Tuesday week days with timezone UTC+01:00 +* `1 2 3 F,4,L 5 2021` for triggering in near first second of second minute of third hour of first, fifth and last days of may of 2021st year +* `1 2 3 F,4,L 5 2021 60o` for triggering in near first second of second minute of third hour of first, fifth and last days of may of 2021st year with timezone UTC+01:00 +* `1 2 3 F,4,L 5 2021 60o 0-2w` for triggering in near first second of second minute of third hour of first, fifth and last days of may of 2021st year if it will be in Sunday-Tuesday week days with timezone UTC+01:00 +* `1 2 3 F,4,L 5 2021 60o 0-2w 500ms` for triggering in near first second of second minute of third hour of first, fifth and last days of may of 2021st year if it will be in Sunday-Tuesday week days with timezone UTC+01:00 when milliseconds will be equal to 500 \ No newline at end of file diff --git a/docs/krontab/introduction/faq.md b/docs/krontab/introduction/faq.md new file mode 100644 index 0000000..6554f73 --- /dev/null +++ b/docs/krontab/introduction/faq.md @@ -0,0 +1,19 @@ +# FAQ + +#### How oftern new versions are releasing? + +Not very often. It depend on libraries (coroutines, korlibs/klock) updates and on some new awesome, but lightweight, features coming. + +#### Where this library could be useful? + +First of all, this library will be useful for long uptime applications which have some tasks to do from time to time. + +#### How to use crontab-like syntax? + +In two words, you should call `buildSchedule` or `createSimpleScheduler`: + +```kotlin +buildSchedule("5 * * * *").asFlow().collect { /* do something */ } +``` + +You can read more about syntax in [String format](../describing/string-format.md) section. \ No newline at end of file diff --git a/docs/krontab/introduction/how-to-use.md b/docs/krontab/introduction/how-to-use.md new file mode 100644 index 0000000..4774928 --- /dev/null +++ b/docs/krontab/introduction/how-to-use.md @@ -0,0 +1,57 @@ +# How to use + +## Previous pages + +* [Including in project](including-in-project.md) + +## `buildSchedule` + +> NOTE: **Custom KronScheduler** +> You always able to create your own scheduler. In this section will be presented different ways and examples around standard `CronDateTimeScheduler` builders `buildSchedule`. You can read about schedulers in [KrontabScheduler](../describing/krontabscheduler.md) + +Currently, `buildSchedule` is the recommended start point for every scheduler. Usually, it is look like: + +```kotlin +val scheduler = buildSchedule("5 * * * *") +``` + +Or: + +```kotlin +val scheduler = buildSchedule { + seconds { + at(5) + } +} +``` + +On the top of any `KronScheduler` currently there are several groups of extensions: + +* Executes +* Shortcuts +* Flows + +### Executes + +All executes are look like `do...`. All executes are described below: + +* `doOnce` - will get the next time for executing, delay until that time and call `block` with returning of the `block` result +* `doWhile` - will call `doOnce` while it will return `true` (that means that `block` must return `true` if it expects that next call must happen). In two words: it will run while `block` returning `true` +* `doInfinity` - will call the `block` using `doWhile` with predefined returning `true`. In two words: it will call `block` while it do not throw error + +### Shortcuts + +Shortcuts are the constants that are initializing in a lazy way to provide preset `KronScheduler`s. For more info about `KrontabScheduler` you can read its own [page](../describing/krontabscheduler.md). + +* `AnyTimeScheduler` - will always return incoming `DateTime` as next +* `Every*Scheduler` - return near * since the passed `relatively`: + * `EverySecondScheduler` + * `EveryMinuteScheduler` + * `EveryHourScheduler` + * `EveryDayOfMonthScheduler` + * `EveryMonthScheduler` + * `EveryYearScheduler` + +### Flows + +Here currently there is only one extension for `KronScheduler`: `KronScheduler#asFlow`. As a result you will get `Flow` (in fact `SchedulerFlow`) which will trigger next `emit` on each not null `next` `DateTime` \ No newline at end of file diff --git a/docs/krontab/introduction/including-in-project.md b/docs/krontab/introduction/including-in-project.md new file mode 100644 index 0000000..d160359 --- /dev/null +++ b/docs/krontab/introduction/including-in-project.md @@ -0,0 +1,35 @@ +# Including in project + +In two words, you must add dependency `dev.inmo:krontab:$krontab_version` to your project. The latest version presented by next badge: + + [![Maven Central](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab/badge.svg)](https://maven-badges.herokuapp.com/maven-central/dev.inmo/krontab) + +### Notice about repository + +To use this library, you will need to include `MavenCentral` repository in you project + +###### build.gradle + +```groovy +mavenCentral() +``` + +### Dependencies + +Next snippets must be placed into your `dependencies` part of `build.gradle` (for gradle) or `pom.xml` (for maven). + +#### Gradle + +```groovy +implementation "dev.inmo:krontab:$krontab_version" +``` + +#### Maven + +```xml + + dev.inmo + krontab + ${krontab_version} + +``` \ No newline at end of file diff --git a/docs/tgbotapi/introduction/before-any-bot-project.md b/docs/tgbotapi/introduction/before-any-bot-project.md index 56c29ae..7c85515 100644 --- a/docs/tgbotapi/introduction/before-any-bot-project.md +++ b/docs/tgbotapi/introduction/before-any-bot-project.md @@ -9,4 +9,4 @@ Anyway, the most important link is [How do I create a bot?](https://core.telegra ## Next steps -* [Including in your project](including-in-your-project.html) +* [Including in your project](including-in-your-project.md) diff --git a/docs/tgbotapi/introduction/including-in-your-project.md b/docs/tgbotapi/introduction/including-in-your-project.md index af6e551..239c61c 100644 --- a/docs/tgbotapi/introduction/including-in-your-project.md +++ b/docs/tgbotapi/introduction/including-in-your-project.md @@ -150,5 +150,5 @@ implementation "dev.inmo:tgbotapi.utils:$tgbotapi_version" ## Next steps -* [Proxy setup](proxy-setup.html) -* [First bot](first-bot.html) +* [Proxy setup](proxy-setup.md) +* [First bot](first-bot.md) diff --git a/docs/tgbotapi/introduction/proxy-setup.md b/docs/tgbotapi/introduction/proxy-setup.md index 9d262c0..e045846 100644 --- a/docs/tgbotapi/introduction/proxy-setup.md +++ b/docs/tgbotapi/introduction/proxy-setup.md @@ -56,4 +56,4 @@ Explanation line by line: ## Next steps -* [First bot](first-bot.html) \ No newline at end of file +* [First bot](first-bot.md) \ No newline at end of file diff --git a/docs/tgbotapi/logic/low-level-work-with-bots.md b/docs/tgbotapi/logic/low-level-work-with-bots.md index ba142ec..80c09cb 100644 --- a/docs/tgbotapi/logic/low-level-work-with-bots.md +++ b/docs/tgbotapi/logic/low-level-work-with-bots.md @@ -10,7 +10,7 @@ There are several important things in context of this library: * [Types](https://github.com/InsanusMokrassar/TelegramBotAPI/tree/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types) * [Requests](https://github.com/InsanusMokrassar/TelegramBotAPI/tree/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests) -So, in most cases all your request calls with simplified api of this library (like `bot.getMe()`) will looks like `bot.execute(GetMe)`. Result of these calls is defined in type of any request (for example, for [GetMe](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/bot/GetMe.kt) request the result type is [ExtendedBot](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/Extended.kt#L101)). As a result, you can avoid any extension api (like [special API extensions](api-extensions.html)) and use low level request with full controlling of the whole logic flow. +So, in most cases all your request calls with simplified api of this library (like `bot.getMe()`) will looks like `bot.execute(GetMe)`. Result of these calls is defined in type of any request (for example, for [GetMe](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/requests/bot/GetMe.kt) request the result type is [ExtendedBot](https://github.com/InsanusMokrassar/TelegramBotAPI/blob/master/tgbotapi.core/src/commonMain/kotlin/dev/inmo/tgbotapi/types/chat/Extended.kt#L101)). As a result, you can avoid any extension api (like [special API extensions](api-extensions.md)) and use low level request with full controlling of the whole logic flow. ## How to handle updates @@ -24,4 +24,4 @@ Result type of [GetUpdates](https://github.com/InsanusMokrassar/TelegramBotAPI/b ## What is next? -As was said above, you may look into our [API extensions](api-extensions.html) in case you wish to use more high-level functions instead of `bot.execute(SomeRequest())`. Besides, it will be very useful to know more about [updates retrieving](../updates). \ No newline at end of file +As was said above, you may look into our [API extensions](api-extensions.md) in case you wish to use more high-level functions instead of `bot.execute(SomeRequest())`. Besides, it will be very useful to know more about [updates retrieving](../updates). \ No newline at end of file diff --git a/docs/tgbotapi/updates/heroku.md b/docs/tgbotapi/updates/heroku.md index ca94c81..ab287af 100644 --- a/docs/tgbotapi/updates/heroku.md +++ b/docs/tgbotapi/updates/heroku.md @@ -2,7 +2,7 @@ > NOTE: **Preview reading** > -> It is recommended to visit our pages about [UpdatesFilters](updates-filters.html) and [Webhooks](webhooks.html) to have more clear understanding about what is happening in this examples page +> It is recommended to visit our pages about [UpdatesFilters](updates-filters.md) and [Webhooks](webhooks.md) to have more clear understanding about what is happening in this examples page [Heroku](https://heroku.com/) is a popular place for bots hosting. In common case you will need to configure webhooks for your server to include getting updates without problems. There are several things related to heroku you should know: @@ -11,7 +11,7 @@ * Currently (`Sat Aug 15 5:04:21 +00 2020`) there is only one official server engine for ktor which is correctly working with Heroku: [Tomcat server engine](https://ktor.io/servers/configuration.html#tomcat) > NOTE: **Server configuration alternatives** -> Here will be presented variants of configuration of webhooks and starting server. You always able to set webhook manualy, create your own ktor server and include webhooks handling in it or create and start server with only webhooks handling. More info you can get on page [Webhooks](webhooks.html) +> Here will be presented variants of configuration of webhooks and starting server. You always able to set webhook manualy, create your own ktor server and include webhooks handling in it or create and start server with only webhooks handling. More info you can get on page [Webhooks](webhooks.md) ### Short example with Behaviour Builder diff --git a/docs/tgbotapi/updates/long-polling.md b/docs/tgbotapi/updates/long-polling.md index ec9b8eb..39b5628 100644 --- a/docs/tgbotapi/updates/long-polling.md +++ b/docs/tgbotapi/updates/long-polling.md @@ -1,10 +1,10 @@ # Long polling -Long polling is a technology of getting updates for cases you do not have some dedicated server or you have no opportunity to receive updates via [webhooks](webhooks.html). More about this you can read in [wiki](https://en.wikipedia.org/wiki/Push_technology#Long_polling). +Long polling is a technology of getting updates for cases you do not have some dedicated server or you have no opportunity to receive updates via [webhooks](webhooks.md). More about this you can read in [wiki](https://en.wikipedia.org/wiki/Push_technology#Long_polling). ## Related topics -* [Updates filters](updates-filters.html) +* [Updates filters](updates-filters.md) ## Long polling in this library @@ -55,5 +55,5 @@ bot.startGettingOfUpdatesByLongPolling { ## See also -* [Webhooks](webhooks.html) -* [Updates filters](updates-filters.html) \ No newline at end of file +* [Webhooks](webhooks.md) +* [Updates filters](updates-filters.md) \ No newline at end of file diff --git a/docs/tgbotapi/updates/updates-filters.md b/docs/tgbotapi/updates/updates-filters.md index 1446f75..94aca2c 100644 --- a/docs/tgbotapi/updates/updates-filters.md +++ b/docs/tgbotapi/updates/updates-filters.md @@ -9,7 +9,7 @@ Due to the fact, that anyway you will get updates in one format (`Update` object * `asUpdateReceiver` - required to represent this filter as common updates receiver which able to get any `Update` * `allowedUpdates` - required to determine, which updates are usefull for this filter -Anyway, this filter can't work with updates by itself. For retrieving updates you should pass this filter to some of getting updates functions ([long polling](long-polling) or [webhooks](webhooks.html)). +Anyway, this filter can't work with updates by itself. For retrieving updates you should pass this filter to some of getting updates functions ([long polling](long-polling) or [webhooks](webhooks.md)). ### SimpleUpdatesFilter @@ -119,5 +119,5 @@ flowsUpdatesFilter { ## See also -* [Long polling](long-polling.html) -* [Webhooks](webhooks.html) \ No newline at end of file +* [Long polling](long-polling.md) +* [Webhooks](webhooks.md) \ No newline at end of file diff --git a/docs/tgbotapi/updates/webhooks.md b/docs/tgbotapi/updates/webhooks.md index e6d44f7..4985539 100644 --- a/docs/tgbotapi/updates/webhooks.md +++ b/docs/tgbotapi/updates/webhooks.md @@ -122,5 +122,5 @@ In the example above server will started and binded for listening on `0.0.0.0:80 ## See also -* [Updates filters](updates-filters.html) -* [Long polling](long-polling.html) \ No newline at end of file +* [Updates filters](updates-filters.md) +* [Long polling](long-polling.md) \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 4da6c1b..45d220b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -21,6 +21,14 @@ nav: - 'tgbotapi/updates/heroku.md' - Logic handling: 'tgbotapi/logic/' - DSLs: 'tgbotapi/dsls/' + - 'Krontab': + - Introduction: + - 'krontab/introduction/including-in-project.md' + - 'krontab/introduction/how-to-use.md' + - 'krontab/introduction/faq.md' + - Describing: + - 'krontab/describing/string-format.md' + - 'krontab/describing/krontabscheduler.md' use_directory_urls: false