clox 0.6__tar.gz → 0.8__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of clox might be problematic. Click here for more details.

@@ -5,6 +5,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6
6
 
7
7
  ## [Unreleased]
8
+ ## [0.8] - 2025-03-16
9
+ ### Added
10
+ - `--country` argument
11
+ - `--countries-list` argument
12
+ - `COUNTRIES.md`
13
+ ### Changed
14
+ - Input case sensitivity bug fixed
15
+ - Test system modified
16
+ - `README.md` updated
17
+ ## [0.7] - 2025-03-06
18
+ ### Added
19
+ - Jalali calendar
20
+ - `--date-system` argument
21
+ ### Changed
22
+ - `README.md` updated
8
23
  ## [0.6] - 2025-02-25
9
24
  ### Added
10
25
  - `--calendar` argument
@@ -43,7 +58,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
43
58
  - `TIMEZONES.md`
44
59
  - `FACES.md`
45
60
 
46
- [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v0.6...dev
61
+ [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v0.8...dev
62
+ [0.8]: https://github.com/sepandhaghighi/clox/compare/v0.7...v0.8
63
+ [0.7]: https://github.com/sepandhaghighi/clox/compare/v0.6...v0.7
47
64
  [0.6]: https://github.com/sepandhaghighi/clox/compare/v0.5...v0.6
48
65
  [0.5]: https://github.com/sepandhaghighi/clox/compare/v0.4...v0.5
49
66
  [0.4]: https://github.com/sepandhaghighi/clox/compare/v0.3...v0.4
clox-0.8/COUNTRIES.md ADDED
@@ -0,0 +1,252 @@
1
+ # Countries List
2
+
3
+ **Last Update: 2025-03-11**
4
+
5
+
6
+ 1. AD - Andorra
7
+ 2. AE - United Arab Emirates
8
+ 3. AF - Afghanistan
9
+ 4. AG - Antigua & Barbuda
10
+ 5. AI - Anguilla
11
+ 6. AL - Albania
12
+ 7. AM - Armenia
13
+ 8. AO - Angola
14
+ 9. AQ - Antarctica
15
+ 10. AR - Argentina
16
+ 11. AS - Samoa (American)
17
+ 12. AT - Austria
18
+ 13. AU - Australia
19
+ 14. AW - Aruba
20
+ 15. AX - Åland Islands
21
+ 16. AZ - Azerbaijan
22
+ 17. BA - Bosnia & Herzegovina
23
+ 18. BB - Barbados
24
+ 19. BD - Bangladesh
25
+ 20. BE - Belgium
26
+ 21. BF - Burkina Faso
27
+ 22. BG - Bulgaria
28
+ 23. BH - Bahrain
29
+ 24. BI - Burundi
30
+ 25. BJ - Benin
31
+ 26. BL - St Barthelemy
32
+ 27. BM - Bermuda
33
+ 28. BN - Brunei
34
+ 29. BO - Bolivia
35
+ 30. BQ - Caribbean NL
36
+ 31. BR - Brazil
37
+ 32. BS - Bahamas
38
+ 33. BT - Bhutan
39
+ 34. BW - Botswana
40
+ 35. BY - Belarus
41
+ 36. BZ - Belize
42
+ 37. CA - Canada
43
+ 38. CC - Cocos (Keeling) Islands
44
+ 39. CD - Congo (Dem. Rep.)
45
+ 40. CF - Central African Rep.
46
+ 41. CG - Congo (Rep.)
47
+ 42. CH - Switzerland
48
+ 43. CI - Côte d'Ivoire
49
+ 44. CK - Cook Islands
50
+ 45. CL - Chile
51
+ 46. CM - Cameroon
52
+ 47. CN - China
53
+ 48. CO - Colombia
54
+ 49. CR - Costa Rica
55
+ 50. CU - Cuba
56
+ 51. CV - Cape Verde
57
+ 52. CW - Curaçao
58
+ 53. CX - Christmas Island
59
+ 54. CY - Cyprus
60
+ 55. CZ - Czech Republic
61
+ 56. DE - Germany
62
+ 57. DJ - Djibouti
63
+ 58. DK - Denmark
64
+ 59. DM - Dominica
65
+ 60. DO - Dominican Republic
66
+ 61. DZ - Algeria
67
+ 62. EC - Ecuador
68
+ 63. EE - Estonia
69
+ 64. EG - Egypt
70
+ 65. EH - Western Sahara
71
+ 66. ER - Eritrea
72
+ 67. ES - Spain
73
+ 68. ET - Ethiopia
74
+ 69. FI - Finland
75
+ 70. FJ - Fiji
76
+ 71. FK - Falkland Islands
77
+ 72. FM - Micronesia
78
+ 73. FO - Faroe Islands
79
+ 74. FR - France
80
+ 75. GA - Gabon
81
+ 76. GB - Britain (UK)
82
+ 77. GD - Grenada
83
+ 78. GE - Georgia
84
+ 79. GF - French Guiana
85
+ 80. GG - Guernsey
86
+ 81. GH - Ghana
87
+ 82. GI - Gibraltar
88
+ 83. GL - Greenland
89
+ 84. GM - Gambia
90
+ 85. GN - Guinea
91
+ 86. GP - Guadeloupe
92
+ 87. GQ - Equatorial Guinea
93
+ 88. GR - Greece
94
+ 89. GS - South Georgia & the South Sandwich Islands
95
+ 90. GT - Guatemala
96
+ 91. GU - Guam
97
+ 92. GW - Guinea-Bissau
98
+ 93. GY - Guyana
99
+ 94. HK - Hong Kong
100
+ 95. HN - Honduras
101
+ 96. HR - Croatia
102
+ 97. HT - Haiti
103
+ 98. HU - Hungary
104
+ 99. ID - Indonesia
105
+ 100. IE - Ireland
106
+ 101. IL - Israel
107
+ 102. IM - Isle of Man
108
+ 103. IN - India
109
+ 104. IO - British Indian Ocean Territory
110
+ 105. IQ - Iraq
111
+ 106. IR - Iran
112
+ 107. IS - Iceland
113
+ 108. IT - Italy
114
+ 109. JE - Jersey
115
+ 110. JM - Jamaica
116
+ 111. JO - Jordan
117
+ 112. JP - Japan
118
+ 113. KE - Kenya
119
+ 114. KG - Kyrgyzstan
120
+ 115. KH - Cambodia
121
+ 116. KI - Kiribati
122
+ 117. KM - Comoros
123
+ 118. KN - St Kitts & Nevis
124
+ 119. KP - Korea (North)
125
+ 120. KR - Korea (South)
126
+ 121. KW - Kuwait
127
+ 122. KY - Cayman Islands
128
+ 123. KZ - Kazakhstan
129
+ 124. LA - Laos
130
+ 125. LB - Lebanon
131
+ 126. LC - St Lucia
132
+ 127. LI - Liechtenstein
133
+ 128. LK - Sri Lanka
134
+ 129. LR - Liberia
135
+ 130. LS - Lesotho
136
+ 131. LT - Lithuania
137
+ 132. LU - Luxembourg
138
+ 133. LV - Latvia
139
+ 134. LY - Libya
140
+ 135. MA - Morocco
141
+ 136. MC - Monaco
142
+ 137. MD - Moldova
143
+ 138. ME - Montenegro
144
+ 139. MF - St Martin (French)
145
+ 140. MG - Madagascar
146
+ 141. MH - Marshall Islands
147
+ 142. MK - North Macedonia
148
+ 143. ML - Mali
149
+ 144. MM - Myanmar (Burma)
150
+ 145. MN - Mongolia
151
+ 146. MO - Macau
152
+ 147. MP - Northern Mariana Islands
153
+ 148. MQ - Martinique
154
+ 149. MR - Mauritania
155
+ 150. MS - Montserrat
156
+ 151. MT - Malta
157
+ 152. MU - Mauritius
158
+ 153. MV - Maldives
159
+ 154. MW - Malawi
160
+ 155. MX - Mexico
161
+ 156. MY - Malaysia
162
+ 157. MZ - Mozambique
163
+ 158. NA - Namibia
164
+ 159. NC - New Caledonia
165
+ 160. NE - Niger
166
+ 161. NF - Norfolk Island
167
+ 162. NG - Nigeria
168
+ 163. NI - Nicaragua
169
+ 164. NL - Netherlands
170
+ 165. NO - Norway
171
+ 166. NP - Nepal
172
+ 167. NR - Nauru
173
+ 168. NU - Niue
174
+ 169. NZ - New Zealand
175
+ 170. OM - Oman
176
+ 171. PA - Panama
177
+ 172. PE - Peru
178
+ 173. PF - French Polynesia
179
+ 174. PG - Papua New Guinea
180
+ 175. PH - Philippines
181
+ 176. PK - Pakistan
182
+ 177. PL - Poland
183
+ 178. PM - St Pierre & Miquelon
184
+ 179. PN - Pitcairn
185
+ 180. PR - Puerto Rico
186
+ 181. PS - Palestine
187
+ 182. PT - Portugal
188
+ 183. PW - Palau
189
+ 184. PY - Paraguay
190
+ 185. QA - Qatar
191
+ 186. RE - Réunion
192
+ 187. RO - Romania
193
+ 188. RS - Serbia
194
+ 189. RU - Russia
195
+ 190. RW - Rwanda
196
+ 191. SA - Saudi Arabia
197
+ 192. SB - Solomon Islands
198
+ 193. SC - Seychelles
199
+ 194. SD - Sudan
200
+ 195. SE - Sweden
201
+ 196. SG - Singapore
202
+ 197. SH - St Helena
203
+ 198. SI - Slovenia
204
+ 199. SJ - Svalbard & Jan Mayen
205
+ 200. SK - Slovakia
206
+ 201. SL - Sierra Leone
207
+ 202. SM - San Marino
208
+ 203. SN - Senegal
209
+ 204. SO - Somalia
210
+ 205. SR - Suriname
211
+ 206. SS - South Sudan
212
+ 207. ST - Sao Tome & Principe
213
+ 208. SV - El Salvador
214
+ 209. SX - St Maarten (Dutch)
215
+ 210. SY - Syria
216
+ 211. SZ - Eswatini (Swaziland)
217
+ 212. TC - Turks & Caicos Is
218
+ 213. TD - Chad
219
+ 214. TF - French Southern & Antarctic Lands
220
+ 215. TG - Togo
221
+ 216. TH - Thailand
222
+ 217. TJ - Tajikistan
223
+ 218. TK - Tokelau
224
+ 219. TL - East Timor
225
+ 220. TM - Turkmenistan
226
+ 221. TN - Tunisia
227
+ 222. TO - Tonga
228
+ 223. TR - Turkey
229
+ 224. TT - Trinidad & Tobago
230
+ 225. TV - Tuvalu
231
+ 226. TW - Taiwan
232
+ 227. TZ - Tanzania
233
+ 228. UA - Ukraine
234
+ 229. UG - Uganda
235
+ 230. UM - US minor outlying islands
236
+ 231. US - United States
237
+ 232. UY - Uruguay
238
+ 233. UZ - Uzbekistan
239
+ 234. VA - Vatican City
240
+ 235. VC - St Vincent
241
+ 236. VE - Venezuela
242
+ 237. VG - Virgin Islands (UK)
243
+ 238. VI - Virgin Islands (US)
244
+ 239. VN - Vietnam
245
+ 240. VU - Vanuatu
246
+ 241. WF - Wallis & Futuna
247
+ 242. WS - Samoa (western)
248
+ 243. YE - Yemen
249
+ 244. YT - Mayotte
250
+ 245. ZA - South Africa
251
+ 246. ZM - Zambia
252
+ 247. ZW - Zimbabwe
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: clox
3
- Version: 0.6
3
+ Version: 0.8
4
4
  Summary: A Geeky Clock for Terminal Enthusiasts
5
5
  Home-page: https://github.com/sepandhaghighi/clox
6
- Download-URL: https://github.com/sepandhaghighi/clox/tarball/v0.6
6
+ Download-URL: https://github.com/sepandhaghighi/clox/tarball/v0.8
7
7
  Author: Sepand Haghighi
8
8
  Author-email: me@sepand.tech
9
9
  License: MIT
@@ -32,6 +32,7 @@ Description-Content-Type: text/markdown
32
32
  License-File: LICENSE
33
33
  License-File: AUTHORS.md
34
34
  Requires-Dist: art>=5.3
35
+ Requires-Dist: jdatetime>=3.8.2
35
36
  Requires-Dist: pytz>=2019.2
36
37
  Dynamic: author
37
38
  Dynamic: author-email
@@ -103,13 +104,13 @@ Clox is a terminal-based clock application designed for terminal enthusiasts who
103
104
  ## Installation
104
105
 
105
106
  ### Source Code
106
- - Download [Version 0.6](https://github.com/sepandhaghighi/clox/archive/v0.6.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
107
+ - Download [Version 0.8](https://github.com/sepandhaghighi/clox/archive/v0.8.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
107
108
  - `pip install .`
108
109
 
109
110
  ### PyPI
110
111
 
111
112
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
112
- - `pip install clox==0.6`
113
+ - `pip install clox==0.8`
113
114
 
114
115
 
115
116
  ## Usage
@@ -142,16 +143,30 @@ clox
142
143
  clox --face=3
143
144
  ```
144
145
  * Use `--face=-1` for random mode
145
- * [Faces List](https://github.com/sepandhaghighi/clox/blob/main/FACES.md)
146
- * `clox --faces-list`
146
+ * [Faces List](https://github.com/sepandhaghighi/clox/blob/main/FACES.md): `clox --faces-list`
147
+
147
148
 
148
149
  ### Timezone
149
150
 
150
151
  ```console
151
152
  clox --timezone="Etc/GMT+7"
152
153
  ```
153
- * [Timezones List](https://github.com/sepandhaghighi/clox/blob/main/TIMEZONES.md)
154
- * `clox --timezones-list`
154
+ * [Timezones List](https://github.com/sepandhaghighi/clox/blob/main/TIMEZONES.md): `clox --timezones-list`
155
+
156
+
157
+ ### Country
158
+
159
+ The `--country` argument allows you to specify a country using its **ISO 3166** code format
160
+
161
+ ℹ️ When the `--country` argument is provided, the `--timezone` argument will be ignored
162
+
163
+ ℹ️ If the specified country has multiple timezones, the first timezone will be selected automatically
164
+
165
+ ```console
166
+ clox --country="DE"
167
+ ```
168
+ * [Countries List](https://github.com/sepandhaghighi/clox/blob/main/COUNTRIES.md): `clox --countries-list`
169
+
155
170
 
156
171
  ### Vertical/Horizontal Shift
157
172
 
@@ -209,6 +224,16 @@ In this mode, the calendar will be displayed
209
224
  clox --calendar=month
210
225
  ```
211
226
 
227
+ ### Date System
228
+
229
+ ℹ️ Valid choices: [`gregorian`, `jalali`]
230
+
231
+ ℹ️ The default date system is `gregorian`
232
+
233
+ ```console
234
+ clox --date-system=jalali
235
+ ```
236
+
212
237
  ## Screen Record
213
238
 
214
239
  <div align="center">
@@ -267,6 +292,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
267
292
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
268
293
 
269
294
  ## [Unreleased]
295
+ ## [0.8] - 2025-03-16
296
+ ### Added
297
+ - `--country` argument
298
+ - `--countries-list` argument
299
+ - `COUNTRIES.md`
300
+ ### Changed
301
+ - Input case sensitivity bug fixed
302
+ - Test system modified
303
+ - `README.md` updated
304
+ ## [0.7] - 2025-03-06
305
+ ### Added
306
+ - Jalali calendar
307
+ - `--date-system` argument
308
+ ### Changed
309
+ - `README.md` updated
270
310
  ## [0.6] - 2025-02-25
271
311
  ### Added
272
312
  - `--calendar` argument
@@ -305,7 +345,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
305
345
  - `TIMEZONES.md`
306
346
  - `FACES.md`
307
347
 
308
- [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v0.6...dev
348
+ [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v0.8...dev
349
+ [0.8]: https://github.com/sepandhaghighi/clox/compare/v0.7...v0.8
350
+ [0.7]: https://github.com/sepandhaghighi/clox/compare/v0.6...v0.7
309
351
  [0.6]: https://github.com/sepandhaghighi/clox/compare/v0.5...v0.6
310
352
  [0.5]: https://github.com/sepandhaghighi/clox/compare/v0.4...v0.5
311
353
  [0.4]: https://github.com/sepandhaghighi/clox/compare/v0.3...v0.4
@@ -53,13 +53,13 @@ Clox is a terminal-based clock application designed for terminal enthusiasts who
53
53
  ## Installation
54
54
 
55
55
  ### Source Code
56
- - Download [Version 0.6](https://github.com/sepandhaghighi/clox/archive/v0.6.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
56
+ - Download [Version 0.8](https://github.com/sepandhaghighi/clox/archive/v0.8.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
57
57
  - `pip install .`
58
58
 
59
59
  ### PyPI
60
60
 
61
61
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
62
- - `pip install clox==0.6`
62
+ - `pip install clox==0.8`
63
63
 
64
64
 
65
65
  ## Usage
@@ -92,16 +92,30 @@ clox
92
92
  clox --face=3
93
93
  ```
94
94
  * Use `--face=-1` for random mode
95
- * [Faces List](https://github.com/sepandhaghighi/clox/blob/main/FACES.md)
96
- * `clox --faces-list`
95
+ * [Faces List](https://github.com/sepandhaghighi/clox/blob/main/FACES.md): `clox --faces-list`
96
+
97
97
 
98
98
  ### Timezone
99
99
 
100
100
  ```console
101
101
  clox --timezone="Etc/GMT+7"
102
102
  ```
103
- * [Timezones List](https://github.com/sepandhaghighi/clox/blob/main/TIMEZONES.md)
104
- * `clox --timezones-list`
103
+ * [Timezones List](https://github.com/sepandhaghighi/clox/blob/main/TIMEZONES.md): `clox --timezones-list`
104
+
105
+
106
+ ### Country
107
+
108
+ The `--country` argument allows you to specify a country using its **ISO 3166** code format
109
+
110
+ ℹ️ When the `--country` argument is provided, the `--timezone` argument will be ignored
111
+
112
+ ℹ️ If the specified country has multiple timezones, the first timezone will be selected automatically
113
+
114
+ ```console
115
+ clox --country="DE"
116
+ ```
117
+ * [Countries List](https://github.com/sepandhaghighi/clox/blob/main/COUNTRIES.md): `clox --countries-list`
118
+
105
119
 
106
120
  ### Vertical/Horizontal Shift
107
121
 
@@ -159,6 +173,16 @@ In this mode, the calendar will be displayed
159
173
  clox --calendar=month
160
174
  ```
161
175
 
176
+ ### Date System
177
+
178
+ ℹ️ Valid choices: [`gregorian`, `jalali`]
179
+
180
+ ℹ️ The default date system is `gregorian`
181
+
182
+ ```console
183
+ clox --date-system=jalali
184
+ ```
185
+
162
186
  ## Screen Record
163
187
 
164
188
  <div align="center">
@@ -4,8 +4,8 @@
4
4
 
5
5
  | Version | Supported |
6
6
  | ------------- | ------------------ |
7
- | 0.6 | :white_check_mark: |
8
- | < 0.6 | :x: |
7
+ | 0.8 | :white_check_mark: |
8
+ | < 0.8 | :x: |
9
9
 
10
10
  ## Reporting a Vulnerability
11
11
 
@@ -3,17 +3,20 @@
3
3
  import os
4
4
  import sys
5
5
  import time
6
- import calendar
6
+ from calendar import TextCalendar as GregorianCalendar
7
7
  import random
8
8
  import datetime
9
+ import jdatetime
9
10
  import argparse
10
11
  import pytz
11
12
  from art import tprint
13
+ from .jcalendar import TextCalendar as JalaliCalendar
12
14
  from .params import HORIZONTAL_TIME_24H_FORMATS, VERTICAL_TIME_24H_FORMATS
13
15
  from .params import HORIZONTAL_TIME_12H_FORMATS, VERTICAL_TIME_12H_FORMATS
14
- from .params import TIMEZONES_LIST, CLOX_VERSION, DATE_FORMAT
16
+ from .params import CLOX_VERSION, DATE_FORMAT
17
+ from .params import TIMEZONES_LIST, COUNTRIES_LIST
15
18
  from .params import ADDITIONAL_INFO, EXIT_MESSAGE
16
- from .params import FACES_MAP, FACES_LIST, CALENDAR_LIST
19
+ from .params import FACES_MAP, FACES_LIST, CALENDARS_LIST, DATE_SYSTEMS_LIST
17
20
  from .params import HORIZONTAL_FACES_LIST_EXAMPLE, VERTICAL_FACES_LIST_EXAMPLE
18
21
  from .params import CLOX_OVERVIEW, CLOX_REPO
19
22
 
@@ -75,18 +78,45 @@ def show_faces_list(vertical=False):
75
78
  print('=' * 80)
76
79
 
77
80
 
78
- def show_timezones_list():
81
+ def show_timezones_list(country=None):
79
82
  """
80
83
  Show timezones list.
81
84
 
85
+ :param country: country iso3166 code
86
+ :type country: str
82
87
  :return: None
83
88
  """
84
- print("Timezones list:\n")
85
- for index, timezone in enumerate(TIMEZONES_LIST, 1):
89
+ timezones_list = TIMEZONES_LIST
90
+ country_name = "All"
91
+ if country is not None:
92
+ timezones_list = list(map(lambda x: x.upper(), pytz.country_timezones(country)))
93
+ country_name = pytz.country_names[country]
94
+ try:
95
+ print("Timezones list ({country_name}):\n".format(country_name=country_name))
96
+ except Exception:
97
+ print("Timezones list ({country_name}):\n".format(country_name=country.upper()))
98
+ for index, timezone in enumerate(sorted(timezones_list), 1):
86
99
  print("{index}. {timezone}".format(index=index, timezone=timezone))
87
100
 
88
101
 
89
- def print_calendar(mode="month", timezone=None, v_shift=0, h_shift=0):
102
+ def show_countries_list():
103
+ """
104
+ Show countries list.
105
+
106
+ :return: None
107
+ """
108
+ print("Countries list:\n")
109
+ for index, country_code in enumerate(sorted(COUNTRIES_LIST), 1):
110
+ country_name = pytz.country_names[country_code]
111
+ try:
112
+ print("{index}. {country_code} - {country_name}".format(index=index,
113
+ country_code=country_code, country_name=country_name))
114
+ except Exception:
115
+ print("{index}. {country_code} - {country_name}".format(index=index,
116
+ country_code=country_code, country_name=country_code))
117
+
118
+
119
+ def print_calendar(mode="month", timezone=None, country=None, v_shift=0, h_shift=0, date_system="gregorian"):
90
120
  """
91
121
  Print calendar.
92
122
 
@@ -94,34 +124,46 @@ def print_calendar(mode="month", timezone=None, v_shift=0, h_shift=0):
94
124
  :type mode: str
95
125
  :param timezone: timezone
96
126
  :type timezone: str
127
+ :param country: country iso3166 code
128
+ :type country: str
97
129
  :param v_shift: vertical shift
98
130
  :type v_shift: int
99
131
  :param h_shift: horizontal shift
100
132
  :type h_shift: int
133
+ :param date_system: date system
134
+ :type date_system: str
101
135
  :return: None
102
136
  """
137
+ datetime_lib = datetime
138
+ calendar_obj = GregorianCalendar()
139
+ if date_system == "jalali":
140
+ datetime_lib = jdatetime
141
+ calendar_obj = JalaliCalendar()
103
142
  tz = None
104
143
  timezone_str = "Local"
144
+ if country is not None:
145
+ timezone = pytz.country_timezones(country)[0].upper()
105
146
  if timezone is not None:
106
147
  timezone_str = timezone
107
148
  tz = pytz.timezone(timezone)
108
149
  v_shift = max(0, v_shift)
109
150
  h_shift = max(0, h_shift)
110
- datetime_now = datetime.datetime.now(tz=tz)
151
+ datetime_now = datetime_lib.datetime.now(tz=tz)
111
152
  current_date = datetime_now.strftime(DATE_FORMAT)
112
153
  print('\n' * v_shift, end='')
113
154
  print(" " * h_shift, end='')
114
155
  print("Today: {date}".format(date=current_date))
115
156
  print(" " * h_shift, end='')
116
157
  print("Timezone: {timezone}\n".format(timezone=timezone_str))
117
- calendar_str = calendar.month(datetime_now.year, datetime_now.month)
158
+ calendar_str = calendar_obj.formatmonth(datetime_now.year, datetime_now.month)
118
159
  if mode == "year":
119
- calendar_str = calendar.calendar(datetime_now.year)
160
+ calendar_str = calendar_obj.formatyear(datetime_now.year)
120
161
  print("\n".join([" " * h_shift + x for x in calendar_str.split("\n")]))
121
162
 
122
163
 
123
164
  def run_clock(
124
165
  timezone=None,
166
+ country=None,
125
167
  v_shift=0,
126
168
  h_shift=0,
127
169
  face=1,
@@ -129,12 +171,15 @@ def run_clock(
129
171
  vertical=False,
130
172
  hide_date=False,
131
173
  hide_timezone=False,
132
- am_pm=False):
174
+ am_pm=False,
175
+ date_system="gregorian"):
133
176
  """
134
177
  Run clock.
135
178
 
136
179
  :param timezone: timezone
137
180
  :type timezone: str
181
+ :param country: country iso3166 code
182
+ :type country: str
138
183
  :param v_shift: vertical shift
139
184
  :type v_shift: int
140
185
  :param h_shift: horizontal shift
@@ -151,14 +196,21 @@ def run_clock(
151
196
  :type hide_timezone: bool
152
197
  :param am_pm: AM/PM mode flag
153
198
  :type am_pm: bool
199
+ :param date_system: date system
200
+ :type date_system: str
154
201
  :return: None
155
202
  """
203
+ datetime_lib = datetime
204
+ if date_system == "jalali":
205
+ datetime_lib = jdatetime
156
206
  format_index = 0
157
207
  time_formats = HORIZONTAL_TIME_12H_FORMATS if am_pm else HORIZONTAL_TIME_24H_FORMATS
158
208
  if vertical:
159
209
  time_formats = VERTICAL_TIME_12H_FORMATS if am_pm else VERTICAL_TIME_24H_FORMATS
160
210
  tz = None
161
211
  timezone_str = "Local"
212
+ if country is not None:
213
+ timezone = pytz.country_timezones(country)[0].upper()
162
214
  if timezone is not None:
163
215
  timezone_str = timezone
164
216
  tz = pytz.timezone(timezone)
@@ -169,7 +221,7 @@ def run_clock(
169
221
  clear_screen()
170
222
  print('\n' * v_shift, end='')
171
223
  print(" " * h_shift, end='')
172
- datetime_now = datetime.datetime.now(tz=tz)
224
+ datetime_now = datetime_lib.datetime.now(tz=tz)
173
225
  current_time = datetime_now.strftime(time_formats[format_index])
174
226
  current_date = datetime_now.strftime(DATE_FORMAT)
175
227
  tprint(current_time, font=face, sep="\n" + " " * h_shift)
@@ -192,7 +244,8 @@ def main():
192
244
  """
193
245
  parser = argparse.ArgumentParser()
194
246
  parser.epilog = ADDITIONAL_INFO
195
- parser.add_argument('--timezone', help='timezone', type=str, choices=TIMEZONES_LIST)
247
+ parser.add_argument('--timezone', help='timezone', type=str.upper, choices=TIMEZONES_LIST)
248
+ parser.add_argument('--country', help='country (iso3166 code)', type=str.upper, choices=COUNTRIES_LIST)
196
249
  parser.add_argument('--v-shift', help='vertical shift', type=int, default=0)
197
250
  parser.add_argument('--h-shift', help='horizontal shift', type=int, default=0)
198
251
  parser.add_argument('--version', help='version', nargs="?", const=1)
@@ -200,12 +253,19 @@ def main():
200
253
  parser.add_argument('--face', help='face', type=int, choices=FACES_LIST, default=1)
201
254
  parser.add_argument('--faces-list', help='faces list', nargs="?", const=1)
202
255
  parser.add_argument('--timezones-list', help='timezones list', nargs="?", const=1)
256
+ parser.add_argument('--countries-list', help='countries list', nargs="?", const=1)
203
257
  parser.add_argument('--no-blink', help='disable blinking mode', nargs="?", const=1)
204
258
  parser.add_argument('--vertical', help='vertical mode', nargs="?", const=1)
205
259
  parser.add_argument('--hide-date', help='hide date', nargs="?", const=1)
206
260
  parser.add_argument('--hide-timezone', help='hide timezone', nargs="?", const=1)
207
261
  parser.add_argument('--am-pm', help='AM/PM mode', nargs="?", const=1)
208
- parser.add_argument('--calendar', help='calendar mode', type=str, choices=CALENDAR_LIST)
262
+ parser.add_argument('--calendar', help='calendar mode', type=str.lower, choices=CALENDARS_LIST)
263
+ parser.add_argument(
264
+ '--date-system',
265
+ help='date system',
266
+ type=str.lower,
267
+ choices=DATE_SYSTEMS_LIST,
268
+ default="gregorian")
209
269
  args = parser.parse_args()
210
270
  if args.version:
211
271
  print(CLOX_VERSION)
@@ -214,13 +274,22 @@ def main():
214
274
  elif args.faces_list:
215
275
  show_faces_list(vertical=args.vertical)
216
276
  elif args.timezones_list:
217
- show_timezones_list()
277
+ show_timezones_list(args.country)
278
+ elif args.countries_list:
279
+ show_countries_list()
218
280
  elif args.calendar:
219
- print_calendar(mode=args.calendar, timezone=args.timezone, h_shift=args.h_shift, v_shift=args.v_shift)
281
+ print_calendar(
282
+ mode=args.calendar,
283
+ timezone=args.timezone,
284
+ country=args.country,
285
+ h_shift=args.h_shift,
286
+ v_shift=args.v_shift,
287
+ date_system=args.date_system)
220
288
  else:
221
289
  try:
222
290
  run_clock(
223
291
  timezone=args.timezone,
292
+ country=args.country,
224
293
  h_shift=args.h_shift,
225
294
  v_shift=args.v_shift,
226
295
  face=args.face,
@@ -228,6 +297,7 @@ def main():
228
297
  vertical=args.vertical,
229
298
  hide_date=args.hide_date,
230
299
  hide_timezone=args.hide_timezone,
231
- am_pm=args.am_pm)
300
+ am_pm=args.am_pm,
301
+ date_system=args.date_system)
232
302
  except (KeyboardInterrupt, EOFError):
233
303
  print(EXIT_MESSAGE)
@@ -0,0 +1,359 @@
1
+ # -*- coding: utf-8 -*-
2
+ """clox jalali calendar."""
3
+ # Reference: https://github.com/IKermani/jcalendar
4
+ import datetime
5
+ from itertools import repeat
6
+ import jdatetime
7
+
8
+ # Exception raised for bad input (with string parameter for details)
9
+ error = ValueError
10
+
11
+
12
+ # Exceptions raised for bad input
13
+ class IllegalMonthError(ValueError):
14
+ """Illegal month error."""
15
+
16
+ def __init__(self, month):
17
+ """Initiate."""
18
+ self.month = month
19
+
20
+ def __str__(self):
21
+ """Return string representation."""
22
+ return "bad month number %r; must be 1-12" % self.month
23
+
24
+
25
+ class IllegalWeekdayError(ValueError):
26
+ """Illegal weekday error."""
27
+
28
+ def __init__(self, weekday):
29
+ """Initiate."""
30
+ self.weekday = weekday
31
+
32
+ def __str__(self):
33
+ """Return string representation."""
34
+ return "bad weekday number %r; must be 0 (Shanbe) to 6 (Jom'e)" % self.weekday
35
+
36
+
37
+ # Constants for months referenced later
38
+ January = 1
39
+ February = 2
40
+
41
+ Farvardin = 1
42
+ Esfand = 12
43
+
44
+ # Number of days per month (except for Esfand in leap years)
45
+ mdays = [0, 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29]
46
+
47
+ # Full and abbreviated names of weekdays
48
+ day_name = jdatetime.date.j_weekdays_en
49
+ day_abbr = jdatetime.date.j_weekdays_short_en
50
+ # day_abbr = ['Sh', 'Ye', 'Do', 'Se', 'Ch', 'Pa', 'Jo']
51
+
52
+ # Full and abbreviated names of months (1-based arrays!!!)
53
+ month_name = [0] + jdatetime.date.j_months_en
54
+ month_abbr = [0] + jdatetime.date.j_months_short_en
55
+
56
+ # Constants for weekdays
57
+ (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)
58
+ (DOSHANBE, SESHANBE, CHAHARSHANBE, PANJSHANBE, JOME, SHANBE, YEKSHANBE) = range(7)
59
+
60
+
61
+ def isleap(year):
62
+ """Return True for leap years, False for non-leap years."""
63
+ return jdatetime.date(year, 1, 1).isleap()
64
+
65
+
66
+ def leapdays(y1, y2):
67
+ """Return number of leap years in range [y1, y2)."""
68
+ leapdays = 0
69
+
70
+ for year in range(y1, y2):
71
+ if isleap(year):
72
+ leapdays += 1
73
+
74
+ return leapdays
75
+
76
+
77
+ def weekday(year, month, day):
78
+ """Return week-day (0-6 ~ Mon-Sun)."""
79
+ if not datetime.MINYEAR <= year <= datetime.MAXYEAR:
80
+ year = 2000 + year % 400
81
+ return jdatetime.date(year, month, day).weekday()
82
+
83
+
84
+ def monthrange(year, month):
85
+ """Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for year, month."""
86
+ if not 1 <= month <= 12:
87
+ raise IllegalMonthError(month)
88
+ day1 = weekday(year, month, 1)
89
+ ndays = mdays[month] + (month == Esfand and isleap(year))
90
+ return day1, ndays
91
+
92
+
93
+ def _monthlen(year, month):
94
+ """Return length of month."""
95
+ return mdays[month] + (month == Esfand and isleap(year))
96
+
97
+
98
+ def _prevmonth(year, month):
99
+ """Return previous month."""
100
+ if month == 1:
101
+ return year - 1, 12
102
+ else:
103
+ return year, month - 1
104
+
105
+
106
+ def _nextmonth(year, month):
107
+ """Return next month."""
108
+ if month == 12:
109
+ return year + 1, 1
110
+ else:
111
+ return year, month + 1
112
+
113
+
114
+ class Calendar(object):
115
+ """Base calendar class. This class doesn't do any formatting. It simply provides data to subclasses."""
116
+
117
+ def __init__(self, firstweekday=0):
118
+ """Initiate."""
119
+ self.firstweekday = firstweekday # 0 = Doshanbe, 6 = Yekshanbe
120
+
121
+ def getfirstweekday(self):
122
+ """Get first weekday."""
123
+ return self._firstweekday % 7
124
+
125
+ def setfirstweekday(self, firstweekday):
126
+ """Set first weekday."""
127
+ self._firstweekday = firstweekday
128
+
129
+ firstweekday = property(getfirstweekday, setfirstweekday)
130
+
131
+ def iterweekdays(self):
132
+ """Return an iterator for one week of weekday numbers starting with the configured first one."""
133
+ for i in range(self.firstweekday, self.firstweekday + 7):
134
+ yield i % 7
135
+
136
+ def itermonthdates(self, year, month):
137
+ """Return an iterator for one month."""
138
+ for y, m, d in self.itermonthdays3(year, month):
139
+ yield jdatetime.date(y, m, d)
140
+
141
+ def itermonthdays(self, year, month):
142
+ """Like itermonthdates(), but will yield day numbers. For days outside the specified month the day number is 0."""
143
+ day1, ndays = monthrange(year, month)
144
+ days_before = (day1 - self.firstweekday) % 7
145
+ yield from repeat(0, days_before)
146
+ yield from range(1, ndays + 1)
147
+ days_after = (self.firstweekday - day1 - ndays) % 7
148
+ yield from repeat(0, days_after)
149
+
150
+ def itermonthdays2(self, year, month):
151
+ """Like itermonthdates(), but will yield (day number, weekday number) tuples. For days outside the specified month the day number is 0."""
152
+ for i, d in enumerate(self.itermonthdays(year, month), self.firstweekday):
153
+ yield d, i % 7
154
+
155
+ def itermonthdays3(self, year, month):
156
+ """Like itermonthdates(), but will yield (year, month, day) tuples. Can be used for dates outside of datetime.date range."""
157
+ day1, ndays = monthrange(year, month)
158
+ days_before = (day1 - self.firstweekday) % 7
159
+ days_after = (self.firstweekday - day1 - ndays) % 7
160
+ y, m = _prevmonth(year, month)
161
+ end = _monthlen(y, m) + 1
162
+ for d in range(end - days_before, end):
163
+ yield y, m, d
164
+ for d in range(1, ndays + 1):
165
+ yield year, month, d
166
+ y, m = _nextmonth(year, month)
167
+ for d in range(1, days_after + 1):
168
+ yield y, m, d
169
+
170
+ def itermonthdays4(self, year, month):
171
+ """Like itermonthdates(), but will yield (year, month, day, day_of_week) tuples. Can be used for dates outside of datetime.date range."""
172
+ for i, (y, m, d) in enumerate(self.itermonthdays3(year, month)):
173
+ yield y, m, d, (self.firstweekday + i) % 7
174
+
175
+ def monthdatescalendar(self, year, month):
176
+ """Return a matrix (list of lists) representing a month's calendar.Each row represents a week; week entries are datetime.date values."""
177
+ dates = list(self.itermonthdates(year, month))
178
+ return [dates[i:i + 7] for i in range(0, len(dates), 7)]
179
+
180
+ def monthdays2calendar(self, year, month):
181
+ """Return a matrix representing a month's calendar."""
182
+ days = list(self.itermonthdays2(year, month))
183
+ return [days[i:i + 7] for i in range(0, len(days), 7)]
184
+
185
+ def monthdayscalendar(self, year, month):
186
+ """Return a matrix representing a month's calendar."""
187
+ days = list(self.itermonthdays(year, month))
188
+ return [days[i:i + 7] for i in range(0, len(days), 7)]
189
+
190
+ def yeardatescalendar(self, year, width=3):
191
+ """Return the data for the specified year ready for formatting."""
192
+ months = [
193
+ self.monthdatescalendar(year, i)
194
+ for i in range(Farvardin, Farvardin + 12)
195
+ ]
196
+ return [months[i:i + width] for i in range(0, len(months), width)]
197
+
198
+ def yeardays2calendar(self, year, width=3):
199
+ """Return the data for the specified year ready for formatting."""
200
+ months = [
201
+ self.monthdays2calendar(year, i)
202
+ for i in range(Farvardin, Farvardin + 12)
203
+ ]
204
+ return [months[i:i + width] for i in range(0, len(months), width)]
205
+
206
+ def yeardayscalendar(self, year, width=3):
207
+ """Return the data for the specified year ready for formatting."""
208
+ months = [
209
+ self.monthdayscalendar(year, i)
210
+ for i in range(Farvardin, Farvardin + 12)
211
+ ]
212
+ return [months[i:i + width] for i in range(0, len(months), width)]
213
+
214
+
215
+ class TextCalendar(Calendar):
216
+ """Subclass of Calendar that outputs a calendar as a simple plain text similar to the UNIX program cal."""
217
+
218
+ def prweek(self, theweek, width):
219
+ """Print a single week (no newline)."""
220
+ print(self.formatweek(theweek, width), end='')
221
+
222
+ def formatday(self, day, weekday, width):
223
+ """Return a formatted day."""
224
+ if day == 0:
225
+ s = ''
226
+ else:
227
+ s = '%2i' % day # right-align single-digit days
228
+ return s.center(width)
229
+
230
+ def formatweek(self, theweek, width):
231
+ """Return a single week in a string (no newline)."""
232
+ return ' '.join(self.formatday(d, wd, width) for (d, wd) in theweek)
233
+
234
+ def formatweekday(self, day, width):
235
+ """Return a formatted week day name."""
236
+ if width >= 9:
237
+ names = day_name
238
+ else:
239
+ names = day_abbr
240
+ return names[day][:width].center(width)
241
+
242
+ def formatweekheader(self, width):
243
+ """Return a header for a week."""
244
+ return ' '.join(self.formatweekday(i, width) for i in self.iterweekdays())
245
+
246
+ def formatmonthname(self, theyear, themonth, width, withyear=True):
247
+ """Return a formatted month name."""
248
+ s = month_name[themonth]
249
+ if withyear:
250
+ s = "%s %r" % (s, theyear)
251
+ return s.center(width)
252
+
253
+ def prmonth(self, theyear, themonth, w=0, l=0):
254
+ """Print a month's calendar."""
255
+ print(self.formatmonth(theyear, themonth, w, l), end='')
256
+
257
+ def formatmonth(self, theyear, themonth, w=0, l=0):
258
+ """Return a month's calendar string (multi-line)."""
259
+ w = max(2, w)
260
+ l = max(1, l)
261
+ s = self.formatmonthname(theyear, themonth, 7 * (w + 1) - 1)
262
+ s = s.rstrip()
263
+ s += '\n' * l
264
+ s += self.formatweekheader(w).rstrip()
265
+ s += '\n' * l
266
+ for week in self.monthdays2calendar(theyear, themonth):
267
+ s += self.formatweek(week, w).rstrip()
268
+ s += '\n' * l
269
+ return s
270
+
271
+ def formatyear(self, theyear, w=2, l=1, c=6, m=3):
272
+ """Return a year's calendar as a multi-line string."""
273
+ w = max(2, w)
274
+ l = max(1, l)
275
+ c = max(2, c)
276
+ colwidth = (w + 1) * 7 - 1
277
+ v = []
278
+ a = v.append
279
+ a(repr(theyear).center(colwidth * m + c * (m - 1)).rstrip())
280
+ a('\n' * l)
281
+ header = self.formatweekheader(w)
282
+ for (i, row) in enumerate(self.yeardays2calendar(theyear, m)):
283
+ # months in this row
284
+ months = range(m * i + 1, min(m * (i + 1) + 1, 13))
285
+ a('\n' * l)
286
+ names = (self.formatmonthname(theyear, k, colwidth, False)
287
+ for k in months)
288
+ a(formatstring(names, colwidth, c).rstrip())
289
+ a('\n' * l)
290
+ headers = (header for k in months)
291
+ a(formatstring(headers, colwidth, c).rstrip())
292
+ a('\n' * l)
293
+ # max number of weeks for this row
294
+ height = max(len(cal) for cal in row)
295
+ for j in range(height):
296
+ weeks = []
297
+ for cal in row:
298
+ if j >= len(cal):
299
+ weeks.append('')
300
+ else:
301
+ weeks.append(self.formatweek(cal[j], w))
302
+ a(formatstring(weeks, colwidth, c).rstrip())
303
+ a('\n' * l)
304
+ return ''.join(v)
305
+
306
+ def pryear(self, theyear, w=0, l=0, c=6, m=3):
307
+ """Print a year's calendar."""
308
+ print(self.formatyear(theyear, w, l, c, m), end='')
309
+
310
+
311
+ c = TextCalendar()
312
+
313
+ firstweekday = c.getfirstweekday
314
+
315
+
316
+ def setfirstweekday(firstweekday):
317
+ """Set first weekday."""
318
+ if not DOSHANBE <= firstweekday <= YEKSHANBE:
319
+ raise IllegalWeekdayError(firstweekday)
320
+ c.firstweekday = firstweekday
321
+
322
+
323
+ monthcalendar = c.monthdayscalendar
324
+ prweek = c.prweek
325
+ week = c.formatweek
326
+ weekheader = c.formatweekheader
327
+ prmonth = c.prmonth
328
+ month = c.formatmonth
329
+ calendar = c.formatyear
330
+ prcal = c.pryear
331
+
332
+ # Spacing of month columns for multi-column year calendar
333
+ _colwidth = 7 * 3 - 1 # Amount printed by prweek()
334
+ _spacing = 6 # Number of spaces between columns
335
+
336
+
337
+ def format(cols, colwidth=_colwidth, spacing=_spacing):
338
+ """Print multi-column formatting for year calendars."""
339
+ print(formatstring(cols, colwidth, spacing))
340
+
341
+
342
+ def formatstring(cols, colwidth=_colwidth, spacing=_spacing):
343
+ """Return a string formatted from n strings, centered within n columns."""
344
+ spacing *= ' '
345
+ return spacing.join(c.center(colwidth) for c in cols)
346
+
347
+
348
+ EPOCH = 1970
349
+ _EPOCH_ORD = jdatetime.date(EPOCH, 1, 1).toordinal()
350
+
351
+
352
+ def timegm(tuple):
353
+ """Unrelated but handy function to calculate Unix timestamp from GMT."""
354
+ year, month, day, hour, minute, second = tuple[:6]
355
+ days = jdatetime.date(year, month, 1).toordinal() - _EPOCH_ORD + day - 1
356
+ hours = days * 24 + hour
357
+ minutes = hours * 60 + minute
358
+ seconds = minutes * 60 + second
359
+ return seconds
@@ -2,7 +2,7 @@
2
2
  """clox params."""
3
3
  import pytz
4
4
 
5
- CLOX_VERSION = "0.6"
5
+ CLOX_VERSION = "0.8"
6
6
 
7
7
  CLOX_OVERVIEW = '''
8
8
  Clox is a terminal-based clock application designed for terminal enthusiasts who appreciate simplicity,
@@ -24,7 +24,8 @@ HORIZONTAL_TIME_12H_FORMATS = ['%I:%M %p', '%I:%M %p.']
24
24
  VERTICAL_TIME_12H_FORMATS = ['%I\n%M\n%p', '%I\n%M\n%p.']
25
25
  DATE_FORMAT = "%A, %B %d, %Y"
26
26
 
27
- TIMEZONES_LIST = pytz.all_timezones
27
+ TIMEZONES_LIST = list(map(lambda x: x.upper(), pytz.all_timezones))
28
+ COUNTRIES_LIST = list(map(lambda x: x.upper(), pytz.country_timezones.keys()))
28
29
 
29
30
 
30
31
  FACES_MAP = {
@@ -57,4 +58,6 @@ FACES_MAP = {
57
58
 
58
59
  FACES_LIST = [-1] + sorted(FACES_MAP)
59
60
 
60
- CALENDAR_LIST = ["month", "year"]
61
+ CALENDARS_LIST = ["month", "year"]
62
+
63
+ DATE_SYSTEMS_LIST = ["gregorian", "jalali"]
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: clox
3
- Version: 0.6
3
+ Version: 0.8
4
4
  Summary: A Geeky Clock for Terminal Enthusiasts
5
5
  Home-page: https://github.com/sepandhaghighi/clox
6
- Download-URL: https://github.com/sepandhaghighi/clox/tarball/v0.6
6
+ Download-URL: https://github.com/sepandhaghighi/clox/tarball/v0.8
7
7
  Author: Sepand Haghighi
8
8
  Author-email: me@sepand.tech
9
9
  License: MIT
@@ -32,6 +32,7 @@ Description-Content-Type: text/markdown
32
32
  License-File: LICENSE
33
33
  License-File: AUTHORS.md
34
34
  Requires-Dist: art>=5.3
35
+ Requires-Dist: jdatetime>=3.8.2
35
36
  Requires-Dist: pytz>=2019.2
36
37
  Dynamic: author
37
38
  Dynamic: author-email
@@ -103,13 +104,13 @@ Clox is a terminal-based clock application designed for terminal enthusiasts who
103
104
  ## Installation
104
105
 
105
106
  ### Source Code
106
- - Download [Version 0.6](https://github.com/sepandhaghighi/clox/archive/v0.6.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
107
+ - Download [Version 0.8](https://github.com/sepandhaghighi/clox/archive/v0.8.zip) or [Latest Source](https://github.com/sepandhaghighi/clox/archive/dev.zip)
107
108
  - `pip install .`
108
109
 
109
110
  ### PyPI
110
111
 
111
112
  - Check [Python Packaging User Guide](https://packaging.python.org/installing/)
112
- - `pip install clox==0.6`
113
+ - `pip install clox==0.8`
113
114
 
114
115
 
115
116
  ## Usage
@@ -142,16 +143,30 @@ clox
142
143
  clox --face=3
143
144
  ```
144
145
  * Use `--face=-1` for random mode
145
- * [Faces List](https://github.com/sepandhaghighi/clox/blob/main/FACES.md)
146
- * `clox --faces-list`
146
+ * [Faces List](https://github.com/sepandhaghighi/clox/blob/main/FACES.md): `clox --faces-list`
147
+
147
148
 
148
149
  ### Timezone
149
150
 
150
151
  ```console
151
152
  clox --timezone="Etc/GMT+7"
152
153
  ```
153
- * [Timezones List](https://github.com/sepandhaghighi/clox/blob/main/TIMEZONES.md)
154
- * `clox --timezones-list`
154
+ * [Timezones List](https://github.com/sepandhaghighi/clox/blob/main/TIMEZONES.md): `clox --timezones-list`
155
+
156
+
157
+ ### Country
158
+
159
+ The `--country` argument allows you to specify a country using its **ISO 3166** code format
160
+
161
+ ℹ️ When the `--country` argument is provided, the `--timezone` argument will be ignored
162
+
163
+ ℹ️ If the specified country has multiple timezones, the first timezone will be selected automatically
164
+
165
+ ```console
166
+ clox --country="DE"
167
+ ```
168
+ * [Countries List](https://github.com/sepandhaghighi/clox/blob/main/COUNTRIES.md): `clox --countries-list`
169
+
155
170
 
156
171
  ### Vertical/Horizontal Shift
157
172
 
@@ -209,6 +224,16 @@ In this mode, the calendar will be displayed
209
224
  clox --calendar=month
210
225
  ```
211
226
 
227
+ ### Date System
228
+
229
+ ℹ️ Valid choices: [`gregorian`, `jalali`]
230
+
231
+ ℹ️ The default date system is `gregorian`
232
+
233
+ ```console
234
+ clox --date-system=jalali
235
+ ```
236
+
212
237
  ## Screen Record
213
238
 
214
239
  <div align="center">
@@ -267,6 +292,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
267
292
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
268
293
 
269
294
  ## [Unreleased]
295
+ ## [0.8] - 2025-03-16
296
+ ### Added
297
+ - `--country` argument
298
+ - `--countries-list` argument
299
+ - `COUNTRIES.md`
300
+ ### Changed
301
+ - Input case sensitivity bug fixed
302
+ - Test system modified
303
+ - `README.md` updated
304
+ ## [0.7] - 2025-03-06
305
+ ### Added
306
+ - Jalali calendar
307
+ - `--date-system` argument
308
+ ### Changed
309
+ - `README.md` updated
270
310
  ## [0.6] - 2025-02-25
271
311
  ### Added
272
312
  - `--calendar` argument
@@ -305,7 +345,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
305
345
  - `TIMEZONES.md`
306
346
  - `FACES.md`
307
347
 
308
- [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v0.6...dev
348
+ [Unreleased]: https://github.com/sepandhaghighi/clox/compare/v0.8...dev
349
+ [0.8]: https://github.com/sepandhaghighi/clox/compare/v0.7...v0.8
350
+ [0.7]: https://github.com/sepandhaghighi/clox/compare/v0.6...v0.7
309
351
  [0.6]: https://github.com/sepandhaghighi/clox/compare/v0.5...v0.6
310
352
  [0.5]: https://github.com/sepandhaghighi/clox/compare/v0.4...v0.5
311
353
  [0.4]: https://github.com/sepandhaghighi/clox/compare/v0.3...v0.4
@@ -1,5 +1,6 @@
1
1
  AUTHORS.md
2
2
  CHANGELOG.md
3
+ COUNTRIES.md
3
4
  FACES.md
4
5
  LICENSE
5
6
  MANIFEST.in
@@ -12,6 +13,7 @@ setup.py
12
13
  clox/__init__.py
13
14
  clox/__main__.py
14
15
  clox/functions.py
16
+ clox/jcalendar.py
15
17
  clox/params.py
16
18
  clox.egg-info/PKG-INFO
17
19
  clox.egg-info/SOURCES.txt
@@ -1,2 +1,3 @@
1
1
  art>=5.3
2
+ jdatetime>=3.8.2
2
3
  pytz>=2019.2
@@ -1,3 +1,4 @@
1
+ jdatetime==5.2.0
1
2
  pytz==2025.1
2
3
  art==6.4
3
4
  setuptools>=40.8.0
@@ -1,2 +1,3 @@
1
1
  art>=5.3
2
+ jdatetime>=3.8.2
2
3
  pytz>=2019.2
@@ -29,7 +29,7 @@ def read_description():
29
29
  setup(
30
30
  name='clox',
31
31
  packages=['clox'],
32
- version='0.6',
32
+ version='0.8',
33
33
  description='A Geeky Clock for Terminal Enthusiasts',
34
34
  long_description=read_description(),
35
35
  long_description_content_type='text/markdown',
@@ -37,7 +37,7 @@ setup(
37
37
  author='Sepand Haghighi',
38
38
  author_email='me@sepand.tech',
39
39
  url='https://github.com/sepandhaghighi/clox',
40
- download_url='https://github.com/sepandhaghighi/clox/tarball/v0.6',
40
+ download_url='https://github.com/sepandhaghighi/clox/tarball/v0.8',
41
41
  keywords="clock time timer timezone terminal cli geek clox",
42
42
  project_urls={
43
43
  'Source': 'https://github.com/sepandhaghighi/clox'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes