From 979749ff9f6e29d39f97ff9b94d8aa569d4aed67 Mon Sep 17 00:00:00 2001 From: Stephen Meech Date: Sat, 28 Dec 2024 20:39:46 +0000 Subject: [PATCH] New date packages, `date-offset` and `timezone-date` (#147) * New date packages, `date-offset` and `timezone-date` * Minor reformatting --- packages/date-offset/0.1.0/README.md | 26 +++++++ packages/date-offset/0.1.0/_manifest.yml | 7 ++ packages/date-offset/0.1.0/package.yml | 88 ++++++++++++++++++++++ packages/timezone-date/0.1.0/README.md | 29 +++++++ packages/timezone-date/0.1.0/_manifest.yml | 7 ++ packages/timezone-date/0.1.0/_package.yml | 46 +++++++++++ packages/timezone-date/0.1.0/package.yml | 43 +++++++++++ 7 files changed, 246 insertions(+) create mode 100644 packages/date-offset/0.1.0/README.md create mode 100644 packages/date-offset/0.1.0/_manifest.yml create mode 100644 packages/date-offset/0.1.0/package.yml create mode 100644 packages/timezone-date/0.1.0/README.md create mode 100644 packages/timezone-date/0.1.0/_manifest.yml create mode 100644 packages/timezone-date/0.1.0/_package.yml create mode 100644 packages/timezone-date/0.1.0/package.yml diff --git a/packages/date-offset/0.1.0/README.md b/packages/date-offset/0.1.0/README.md new file mode 100644 index 0000000..2d076bf --- /dev/null +++ b/packages/date-offset/0.1.0/README.md @@ -0,0 +1,26 @@ +# Date Offsets + +Espanso's inbuilt `date` extension is handy, but very limited, particularly because it **cannot** accept a `{{variable}}` for its `offset:` value. + +This package contains short Espanso snippets to return dates offset from today, utilising the date-handling facilities of four different scripting languages, partly as an exercise for me in working out how this can be done. + +As supplied, typing a trigger, e.g.: +``` +-18d, +2w, -3m, +5y +``` +will present you with a choice box, listing the different scripts, each of which will return the relevant (hopefully the same!) date. + +Any of the languages you don't have installed will generate Espanso errors: + - Bash (Linux/macOS) or WSL (Windows) + - Powershell (Windows) or pwsh (Linux/macOS) + - Python + - Javascript + +My tests (Linux) indicate that in speed, Bash > Python > Node > PowerShell, but PowerShell is likely to be faster (but not necessarily the *fastest*) in Windows. + +Ultimately, adopt one and delete or comment-out the others you don't need. + +See my package `timezone-date` for timezone offsets. + +Stephen Meech +(@smeech) diff --git a/packages/date-offset/0.1.0/_manifest.yml b/packages/date-offset/0.1.0/_manifest.yml new file mode 100644 index 0000000..7730b68 --- /dev/null +++ b/packages/date-offset/0.1.0/_manifest.yml @@ -0,0 +1,7 @@ +name: "date-offset" +title: "Date Offsets" +description: A package that uses the date-handling facilities of different scripting languages to return dates variably offset from today, as specified in a regex trigger. +homepage: "https://github.com/smeech" +version: 0.1.0 +author: Stephen Meech +tags: [time, date, python, bash, powershell, pwsh, javascript, node.js] diff --git a/packages/date-offset/0.1.0/package.yml b/packages/date-offset/0.1.0/package.yml new file mode 100644 index 0000000..df7d4f9 --- /dev/null +++ b/packages/date-offset/0.1.0/package.yml @@ -0,0 +1,88 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/espanso/espanso/dev/schemas/match.schema.json + + +# Espanso snippets to return offset date from today +# Type e.g.: -18d, +2w, -3m, +5y etc. + +matches: +# Bash version + - regex: (?P[+-]\d+)(?P[dwmy]) + replace: "{{output}}" + label: Bash offset date + vars: + - name: output + type: shell + params: + shell: bash + cmd: | + case {{unit}} in + d) date=$(date -d "{{offset}} days" +"%d/%m/%y") ;; + w) date=$(date -d "{{offset}} weeks" +"%d/%m/%y") ;; + m) date=$(date -d "{{offset}} months" +"%d/%m/%y") ;; + y) date=$(date -d "{{offset}} years" +"%d/%m/%y") ;; + esac + echo "$date" + +# PowerShell version + - regex: (?P[+-]\d+)(?P[dwmy]) + replace: "{{output}}" + label: PowerShell offset date + vars: + - name: output + type: shell + params: + shell: pwsh + cmd: | + switch ("{{unit}}") { + "d" { $date = (Get-Date).AddDays({{offset}}).ToString("dd/MM/yy") } + "w" { $date = (Get-Date).AddDays({{offset}} * 7).ToString("dd/MM/yy") } + "m" { $date = (Get-Date).AddMonths({{offset}}).ToString("dd/MM/yy") } + "y" { $date = (Get-Date).AddYears({{offset}}).ToString("dd/MM/yy") } + } + Write-Output $date + +# Python version + - regex: (?P[+-]\d+)(?P[dwmy]) + replace: "{{output}}" + label: Python offset date + vars: + - name: output + type: script + params: + args: + - python + - -c + - | + from datetime import datetime, timedelta + from dateutil.relativedelta import relativedelta + now = datetime.now() + match "{{unit}}": + case "d": date = now + timedelta(days={{offset}}) + case "w": date = now + timedelta(weeks={{offset}}) + case "m": date = now + relativedelta(months={{offset}}) + case "y": date = now + relativedelta(years={{offset}}) + print(date.strftime("%d/%m/%y")) + +# Javascript version + - regex: (?P[+-]\d+)(?P[dwmy]) + replace: "{{output}}" + label: Javascript offset date + vars: + - name: output + type: script + params: + args: + - node + - -e + - | + let now = new Date(); + switch('{{unit}}') { + case 'd': date = new Date(now.setDate(now.getDate() + {{offset}})); break; + case 'w': date = new Date(now.setDate(now.getDate() + ({{offset}} * 7))); break; + case 'm': date = new Date(now.setMonth(now.getMonth() + {{offset}})); break; + case 'y': date = new Date(now.setFullYear(now.getFullYear() + {{offset}})); break; + } + const day = ("0" + date.getDate()).slice(-2); + const month = ("0" + (date.getMonth() + 1)).slice(-2); + const year = date.getFullYear().toString().slice(-2); + console.log(`${day}/${month}/${year}`); \ No newline at end of file diff --git a/packages/timezone-date/0.1.0/README.md b/packages/timezone-date/0.1.0/README.md new file mode 100644 index 0000000..69e6310 --- /dev/null +++ b/packages/timezone-date/0.1.0/README.md @@ -0,0 +1,29 @@ +# Timezone Date + +A single trigger that uses two Python scripts to offer a choice from the full set of worldwide timezones, returning the current date and time there. + +(Espanso's inbuilt `date` extension is handy, but very limited, especially because it can't accept a `{{variable}}` for its `offset:` value. I'll publish another small package `date-offset` to illustrate other ways in which this can be done.) + +Two versions of the match file are included: + +1. `package.yml` uses the `pytz` library and should work with any version of Python +2. `_package.yml` uses `zoneinfo`, which is part of modern editions (v3.9+) of Python, and should be a few milliseconds faster + +To try the latter, rename the first file to anything you like, with an underscore `_` as its first character so that Espanso ignores it, then *remove* the underscore prefixing the second file's name. + +In the middle of each file is a `default:` line, currently: + +```yml + default: Europe/London +``` + +Once you've tried the trigger, change this timezone value to take you quickly to a part of the list that suits you most - it's a long list! + +There is scope to modify the code to: + +- in the last line, change the text, and date format output +- hard-code a timezone into the third variable (if you only need one, for example), dispensing with the first two variables providing the choice +- include some sort of time offset (do so in the final section but *prior* to the conversion of UTC time to the specified timezone) - see also the `date-offset` package + +Stephen Meech +(@smeech) diff --git a/packages/timezone-date/0.1.0/_manifest.yml b/packages/timezone-date/0.1.0/_manifest.yml new file mode 100644 index 0000000..15d9b65 --- /dev/null +++ b/packages/timezone-date/0.1.0/_manifest.yml @@ -0,0 +1,7 @@ +name: "timezone-date" +title: "Timezone Date" +description: A package that uses Python scripts to offer a choice from the full set of worldwide timezones, returning the current date and time there. +homepage: "https://github.com/smeech" +version: 0.1.0 +author: Stephen Meech +tags: [time, date, timezone, python] diff --git a/packages/timezone-date/0.1.0/_package.yml b/packages/timezone-date/0.1.0/_package.yml new file mode 100644 index 0000000..c7b9326 --- /dev/null +++ b/packages/timezone-date/0.1.0/_package.yml @@ -0,0 +1,46 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/espanso/espanso/dev/schemas/match.schema.json + +# This version will work on newer (v3.9+) versions of Python +# and is probably faster than the one which relies on `pytz` + +# To use it, rename this file, without the underscore `_` prefix +# and rename the other WITH an underscore prefix. + +# Amend the `default: Europe/London` line 32 to suit yourself + +matches: + - trigger: :tzdate + replace: '{{output}}' + vars: + - name: zones + type: script + params: + args: + - python + - -c + - | + from zoneinfo import available_timezones + print("\n".join(sorted(available_timezones()))) + - name: zone_choice + type: form + params: + layout: 'Pick a time-zone: [[zone]]' + fields: + zone: + type: list + values: '{{zones}}' + default: Europe/London # Change this to a timezone that suits you + - name: output + type: script + params: + args: + - python + - -c + - | + from datetime import datetime; from zoneinfo import ZoneInfo + timezone = ZoneInfo('{{zone_choice.zone}}') + # Get the current UTC time + utc_now = datetime.utcnow() + # Convert UTC time to the specified timezone + local_time = utc_now.astimezone(timezone) + print("Current date and time in", timezone, "is:", local_time.strftime('%F %T')) diff --git a/packages/timezone-date/0.1.0/package.yml b/packages/timezone-date/0.1.0/package.yml new file mode 100644 index 0000000..6401186 --- /dev/null +++ b/packages/timezone-date/0.1.0/package.yml @@ -0,0 +1,43 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/espanso/espanso/dev/schemas/match.schema.json + +# This version should work on most versions of Python +# but may be slower than the one which uses `zoneinfo` + +# Amend the `default: Europe/London` line 29 to your convenience + +matches: + - trigger: :tzdate + replace: '{{output}}' + vars: + - name: zones + type: script + params: + args: + - python + - -c + - | + import pytz + print("\n".join(pytz.all_timezones)) + - name: zone_choice + type: form + params: + layout: 'Pick a time-zone: [[zone]]' + fields: + zone: + type: list + values: '{{zones}}' + default: Europe/London # Change this to a timezone that suits you + - name: output + type: script + params: + args: + - python + - -c + - | + import pytz; from datetime import datetime + timezone = pytz.timezone('{{zone_choice.zone}}') + # Get the current date and time in UTC + utc_now = datetime.utcnow().replace(tzinfo=pytz.utc) + # Convert UTC time to the specified timezone + local_time = utc_now.astimezone(timezone) + print("Current date and time in", timezone, "is:", local_time.strftime('%F %T')) \ No newline at end of file