uw-course 1.0.2__py3-none-any.whl → 2.0.0__py3-none-any.whl

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.
@@ -0,0 +1,99 @@
1
+ from textual.containers import Horizontal, Vertical
2
+ from textual.widgets import (
3
+ Button,
4
+ Checkbox,
5
+ DataTable,
6
+ Input,
7
+ Select,
8
+ Static,
9
+ TabbedContent,
10
+ TabPane,
11
+ )
12
+
13
+
14
+ def detail_form_widgets():
15
+ return [
16
+ Input(placeholder="Course code (e.g., CS 136)", id="detail-input"),
17
+ Button("Lookup", id="detail-run", variant="primary"),
18
+ ]
19
+
20
+
21
+ def schedule_term_widgets(collection_options):
22
+ return [
23
+ Select(collection_options, id="schedule-collection", prompt="Select term..."),
24
+ Static("Select a term to configure schedule options.", id="schedule-term-hint"),
25
+ ]
26
+
27
+
28
+ def schedule_action_buttons():
29
+ return Horizontal(
30
+ Button("Export PDF", id="schedule-export"),
31
+ id="schedule-buttons",
32
+ )
33
+
34
+
35
+ class ScheduleTabs(TabbedContent):
36
+ def __init__(self, collection_options, **kwargs):
37
+ super().__init__(**kwargs)
38
+ self._collection_options = collection_options
39
+
40
+ def on_mount(self) -> None:
41
+ self.add_pane(
42
+ TabPane(
43
+ "Build Schedule",
44
+ Vertical(
45
+ *schedule_term_widgets(self._collection_options),
46
+ Input(placeholder="Course code (e.g., CS 136)", id="schedule-course"),
47
+ Input(placeholder="Class ID (optional)", id="schedule-class-id"),
48
+ Horizontal(
49
+ Button("Add Course", id="schedule-add", variant="primary"),
50
+ Button("Clear List", id="schedule-clear", variant="warning"),
51
+ Button("Remove Selected", id="schedule-remove", variant="error"),
52
+ id="schedule-edit-buttons",
53
+ ),
54
+ DataTable(id="schedule-table"),
55
+ Input(
56
+ placeholder="Save config to (default: uw-course-files/schema.txt)",
57
+ id="schedule-save-file",
58
+ ),
59
+ Horizontal(
60
+ Button("Generate Schedule", id="schedule-run", variant="primary"),
61
+ Button("Save Config", id="schedule-save"),
62
+ id="manual-actions",
63
+ ),
64
+ Horizontal(
65
+ Checkbox("Gray color mode", id="schedule-gray"),
66
+ Button("Export PDF", id="schedule-export"),
67
+ id="manual-options",
68
+ ),
69
+ id="manual-pane",
70
+ ),
71
+ id="tab-build",
72
+ )
73
+ )
74
+ self.add_pane(
75
+ TabPane(
76
+ "Load Plan",
77
+ Vertical(
78
+ Input(
79
+ placeholder="Load config file path (default: uw-course-files/schema.txt)",
80
+ id="schedule-load-file",
81
+ ),
82
+ Horizontal(
83
+ Button("Load Config", id="schedule-load", variant="primary"),
84
+ ),
85
+ Horizontal(
86
+ Checkbox("Gray color mode", id="schedule-gray"),
87
+ Button("Export PDF", id="schedule-export"),
88
+ id="load-options",
89
+ ),
90
+ id="load-pane",
91
+ ),
92
+ id="tab-load",
93
+ )
94
+ )
95
+ self.active = "tab-build"
96
+
97
+
98
+ def schedule_tabs_with_options(collection_options):
99
+ return ScheduleTabs(collection_options, id="schedule-tabs")
@@ -0,0 +1,9 @@
1
+ SCHEDULE_PLACEHOLDER = "Generate a schedule to see the weekly view."
2
+ DETAIL_PLACEHOLDER = "Enter a course code to see details here."
3
+
4
+ ACTION_DETAIL = "action-detail"
5
+ ACTION_SCHEDULE = "action-schedule"
6
+ ACTION_QUIT = "action-quit"
7
+
8
+ SIDEBAR_TITLE_DETAIL = "Course Detail"
9
+ SIDEBAR_TITLE_SCHEDULE = "Weekly Schedule"
@@ -0,0 +1,87 @@
1
+ import re
2
+
3
+
4
+ def parse_schedule_out(path):
5
+ items = []
6
+ current = {}
7
+ try:
8
+ with open(path, "r") as handle:
9
+ for raw_line in handle:
10
+ line = raw_line.strip()
11
+ if not line:
12
+ if current:
13
+ items.append(current)
14
+ current = {}
15
+ continue
16
+ if line.startswith("- name:"):
17
+ if current:
18
+ items.append(current)
19
+ current = {}
20
+ current["name"] = line[len("- name:") :].strip()
21
+ elif line.startswith("days:"):
22
+ current["days"] = line[len("days:") :].strip()
23
+ elif line.startswith("time:"):
24
+ current["time"] = line[len("time:") :].strip()
25
+ if current:
26
+ items.append(current)
27
+ except FileNotFoundError:
28
+ return []
29
+ return items
30
+
31
+
32
+ def split_days(days):
33
+ cleaned = re.sub(r"[^A-Za-z]", "", days)
34
+ tokens = re.findall(r"Th|Tu|Sa|Su|[MTWHFSU]", cleaned)
35
+ mapping = {
36
+ "M": "Mon",
37
+ "T": "Tue",
38
+ "Tu": "Tue",
39
+ "W": "Wed",
40
+ "H": "Thu",
41
+ "Th": "Thu",
42
+ "F": "Fri",
43
+ "S": "Sat",
44
+ "Sa": "Sat",
45
+ "U": "Sun",
46
+ "Su": "Sun",
47
+ }
48
+ return [mapping[token] for token in tokens if token in mapping]
49
+
50
+
51
+ def time_to_minutes(raw_time):
52
+ try:
53
+ hours, minutes = raw_time.split(":")
54
+ return int(hours) * 60 + int(minutes)
55
+ except ValueError:
56
+ return 0
57
+
58
+
59
+ def render_weekly_schedule(path):
60
+ items = parse_schedule_out(path)
61
+ if not items:
62
+ return "No schedule generated yet."
63
+
64
+ weekly = {day: [] for day in ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")}
65
+ for item in items:
66
+ name = item.get("name", "").split("Available Seat")[0].strip()
67
+ time_range = item.get("time", "")
68
+ if " - " in time_range:
69
+ start, end = [part.strip() for part in time_range.split(" - ", 1)]
70
+ else:
71
+ start, end = time_range, ""
72
+ for day in split_days(item.get("days", "")):
73
+ weekly[day].append((start, end, name))
74
+
75
+ lines = ["Weekly Schedule"]
76
+ for day in weekly:
77
+ lines.append(f"{day}:")
78
+ entries = sorted(weekly[day], key=lambda x: time_to_minutes(x[0]))
79
+ if not entries:
80
+ lines.append(" (no classes)")
81
+ continue
82
+ for start, end, name in entries:
83
+ if end:
84
+ lines.append(f" {start}-{end} {name}")
85
+ else:
86
+ lines.append(f" {start} {name}")
87
+ return "\n".join(lines)
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.4
2
+ Name: uw-course
3
+ Version: 2.0.0
4
+ Summary: A course helper tool for managing UW courses schedule
5
+ Author-email: Jiucheng Zang <git.jiucheng@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/zangjiucheng/uw-course
8
+ Project-URL: Repository, https://github.com/zangjiucheng/uw-course
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Classifier: Operating System :: MacOS
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Topic :: Education
17
+ Classifier: Topic :: Office/Business :: Scheduling
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: attrs
22
+ Requires-Dist: click
23
+ Requires-Dist: PyYAML
24
+ Requires-Dist: reportlab
25
+ Requires-Dist: certifi
26
+ Requires-Dist: dnspython
27
+ Requires-Dist: Pillow
28
+ Requires-Dist: pymongo
29
+ Requires-Dist: textual
30
+ Dynamic: license-file
31
+
32
+ # uw-course
33
+
34
+ [![PyPI version](https://badge.fury.io/py/uw-course.svg)](https://badge.fury.io/py/uw-course)
35
+
36
+
37
+ This is a project for UWaterloo students to help them get course information and generate a schedule for the next term.
38
+
39
+ MongoDB DashBoard: [LINK](https://charts.mongodb.com/charts-project-0-cbzai/public/dashboards/091bc68f-76df-48c0-aa69-b21af14c0a8a)
40
+
41
+ ### Example Schedule:
42
+
43
+ ![Image text](demo.png)
44
+
45
+ ---
46
+
47
+ ### Install Steps:
48
+ 1. Install Python3 (>= 3.10) [Python Website](https://www.python.org/downloads/)
49
+ 2. ```bash
50
+ pip install uw-course
51
+ ```
52
+
53
+ ---
54
+
55
+ ### Usage (TUI)
56
+
57
+ Run the terminal UI:
58
+ ```bash
59
+ uw-course
60
+ ```
61
+
62
+ You can:
63
+ - Check course details
64
+ - Build a schedule manually or load a plan file
65
+ - View the weekly schedule in the TUI
66
+ - Export the `.out` schedule to PDF
67
+
68
+ #### Schedule Plan File Format
69
+ 1. Create a new file named `schema.txt`
70
+ 2. Edit `schema.txt` with the following format:
71
+ ```txt
72
+ Class{year}{Winter/Spring/Fall}
73
+
74
+ {Course}{CourseName}, {ClassID}
75
+ {Course}{CourseName}, {ClassID}
76
+ ...
77
+ ```
78
+
79
+ Example:
80
+ ```txt
81
+ Class2025Winter
82
+
83
+ PHYS 234, 7166
84
+ CS 431, 8788
85
+ PMATH 351, 6382
86
+ CO 353, 6157
87
+ STAT 231, 6097
88
+ AMATH 250, 5967
89
+ ```
90
+ 3. Use the TUI to select “Load Plan” and provide the file path (default: `uw-course-files/schema.txt`).
91
+ 4. The program will generate `uw-course-files/schedule.out`, and you can export it to PDF from the TUI.
92
+
93
+ #### Output Location
94
+ All generated files are stored in `uw-course-files/`:
95
+ - `uw-course-files/schedule.out`
96
+ - `uw-course-files/schedule.pdf`
97
+ - `uw-course-files/schema.txt` (if saved from the TUI)
98
+
99
+ #### Any Idea or Question, welcome send me an email via: j7zang@uwaterloo.ca
100
+
101
+ ---
102
+
103
+ ## Credits
104
+
105
+ PDF export uses a modified version of `pdfschedule` by John Thorvald Wodder II. Thanks for the original project.
106
+
107
+ ---
108
+
109
+ ## License
110
+
111
+ This project is open-source and can be modified and used for personal or educational purposes. Attribution to the original creator is appreciated. (MIT License)
@@ -0,0 +1,23 @@
1
+ uw_course/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ uw_course/main.py,sha256=sXEHSTgtSV3HurJUbe7OkOzWyd8-UyKj8hoHfzuvjo4,275
3
+ uw_course/pdfschedule.py,sha256=oy4gwgw74H-LbnD0bzds122xLS6UQc0JRO58YnUGomg,12141
4
+ uw_course/setting.py,sha256=pP0fOfAoBPDCV1ENpe0i18HGauDBBcztbXpMdNNit8s,289
5
+ uw_course/ClassSchedule/SearchInfo.py,sha256=SQEbTFxSVOTjF4G0G-7RNuuFeoJY_KRSIFhVpJFBSRY,2118
6
+ uw_course/ClassSchedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ uw_course/ClassSchedule/runner.py,sha256=-rLr-RW828TFOWd2IOgmUB0TUIfKd6tMsb9azU4IgQY,2592
8
+ uw_course/DB/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ uw_course/DB/dbClass.py,sha256=Vu7JpkXn12KoiHJ654oeC-2UD4CDNhiAVYQeFctTTTM,1737
10
+ uw_course/Utiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ uw_course/Utiles/manageDBClass.py,sha256=gIUXup5qM8UsgPuCH1VqF4xBiGzMQTKFGBixX4ImAKw,782
12
+ uw_course/Utiles/randomColor.py,sha256=g5N0SKGeF9AxQXqBpA8ELLdoqHFfOA5AnxTN2j2kLhQ,510
13
+ uw_course/ui/__init__.py,sha256=iYGpX2CrLs7i9ttBsB0tbcRcftNwavvEb22U7LKV2to,32
14
+ uw_course/ui/app.py,sha256=vvrIkjWzXKMktuuF3DmLRj4tvyn3_xS9_3QIF1D1u30,22949
15
+ uw_course/ui/components.py,sha256=Kd-GdE2wd-0v8OFz3M0H5YPkM-IVyd-iskDp6bkGWyE,3492
16
+ uw_course/ui/constants.py,sha256=3bV5H5gA6Hr6iJnav_yLoA8YothiBwqmqDDQybJANco,313
17
+ uw_course/ui/schedule_view.py,sha256=OWBpXkTzL3qxWUeXiemXkGaLNJqpb61YQe9wLhyLkXg,2656
18
+ uw_course-2.0.0.dist-info/licenses/LICENSE,sha256=3gvYdtz3_nCjhGpKAbUQzU1CT9anApYNOrn-bF6ZhI8,1073
19
+ uw_course-2.0.0.dist-info/METADATA,sha256=V76FEovc66vVVJv5CsPgJcSWfX0vSXJcCEqQjTiP0-k,3000
20
+ uw_course-2.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
21
+ uw_course-2.0.0.dist-info/entry_points.txt,sha256=KwZTcAbhGgjmTdkqwUtMDKzhZ1iqGY5OmaH6F7XNgRk,50
22
+ uw_course-2.0.0.dist-info/top_level.txt,sha256=b760hy15dn_4qeUiKj9gQ8jnO9caaRoD-4ks28p81NY,10
23
+ uw_course-2.0.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,9 +0,0 @@
1
- HEADER = '\033[95m'
2
- OKBLUE = '\033[94m'
3
- OKCYAN = '\033[96m'
4
- OKGREEN = '\033[92m'
5
- WARNING = '\033[93m'
6
- FAIL = '\033[91m'
7
- ENDC = '\033[0m'
8
- BOLD = '\033[1m'
9
- UNDERLINE = '\033[4m'
@@ -1,95 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: uw-course
3
- Version: 1.0.2
4
- Summary: A course helper tool for managing UW courses schedule
5
- Author-email: Jiucheng Zang <zangjiucheng@gmail.com>
6
- License: MIT
7
- Project-URL: homepage, https://github.com/zangjiucheng/CourseExplorer
8
- Project-URL: repository, https://github.com/zangjiucheng/CourseExplorer
9
- Requires-Python: >=3.7
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
- Requires-Dist: attrs
13
- Requires-Dist: certifi
14
- Requires-Dist: click
15
- Requires-Dist: dnspython
16
- Requires-Dist: pdfschedule
17
- Requires-Dist: Pillow
18
- Requires-Dist: pymongo
19
- Requires-Dist: PyYAML
20
- Requires-Dist: reportlab
21
-
22
- # uw-course
23
-
24
- [![PyPI version](https://badge.fury.io/py/uw-course.svg)](https://badge.fury.io/py/uw-course)
25
-
26
-
27
- This is a project for UWaterloo students to help them get course information and generate a schedule for the next term.
28
-
29
- MongoDB DashBoard: [LINK](https://charts.mongodb.com/charts-project-0-cbzai/public/dashboards/091bc68f-76df-48c0-aa69-b21af14c0a8a)
30
-
31
- ### Example Schedule:
32
-
33
- ![Image text](demo.png)
34
-
35
- ---
36
-
37
- ### Install Steps:
38
- 1. Install Python3 (>= 3.7) [Python Website](https://www.python.org/downloads/)
39
- 2. ```bash
40
- pip install uw-course
41
- ```
42
-
43
- ---
44
-
45
- ### Usage:
46
-
47
- #### 1. Get Course Information
48
- 1. Run the following command in the terminal
49
- ```bash
50
- uw-course -c "{CourseName}"
51
- ```
52
-
53
- Example:
54
- ```bash
55
- uw-course -c "CO 250"
56
- ```
57
-
58
- #### 2. Get Course Schedule
59
- 1. Create a new file named ```schedule.txt``` in the folder you want to save the schedule
60
- 2. Edit ```schedule.txt``` with the following format:
61
- ```txt
62
- Class{year}{Winter/Summer/Fall}
63
-
64
- {Course}{CourseName}, {ClassID}
65
- {Course}{CourseName}, {ClassID}
66
- ...
67
- ```
68
-
69
- Example:
70
- ```txt
71
- Class2025Winter
72
-
73
- PHYS 234, 7166
74
- CS 431, 8788
75
- PMATH 351, 6382
76
- CO 353, 6157
77
- STAT 231, 6097
78
- AMATH 250, 5967
79
- ```
80
- 3. Run the following command in the folder you saved the ```schedule.txt``` file
81
- ```bash
82
- uw-course -f schedule.txt
83
- ```
84
- (If you want to get the schedule with gray printables, you can add the ```-g``` flag)
85
-
86
- 4. The program will generate a ```schedule.pdf``` file in the same folder, which is the schedule you want to see
87
-
88
- #### Any Idea or Question, welcome send me an email via: j7zang@uwaterloo.ca
89
-
90
- ---
91
-
92
- ## License
93
-
94
- This project is open-source and can be modified and used for personal or educational purposes. Attribution to the original creator is appreciated. (MIT License)
95
-
@@ -1,18 +0,0 @@
1
- uw_course/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- uw_course/main.py,sha256=xcNbcu1OHSGwCEQmdAjzSasy0Or2l3f7JENtmmmx4Po,2888
3
- uw_course/setting.py,sha256=MSJVr85Kc3XMFKW-rFKx34TDJWtbK4axj7TpzO0mTqM,177
4
- uw_course/ClassSchedule/SearchInfo.py,sha256=TWYieCibMtn-AISSSgBUXnuh4fLrsDv1Yn2IIfhI8SM,2168
5
- uw_course/ClassSchedule/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- uw_course/ClassSchedule/runner.py,sha256=ApzVYoSqC2oizwTxaTRvDQQQNJzkeXQTO7ayozfWFmA,2315
7
- uw_course/DB/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- uw_course/DB/dbClass.py,sha256=1R3_8j4PpTlKCkvZvVvyllu04mIk14wcIN9wPEo_m7k,1006
9
- uw_course/Utiles/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
- uw_course/Utiles/colorMessage.py,sha256=HlTn2saR96Sh5jRjBZ_P8EvHrzORxOR6-Zzu0ATHuw0,176
11
- uw_course/Utiles/manageDBClass.py,sha256=0V721lervaRzJyiFHgQrUovNKNYba8uiD9WIEeQLAe4,641
12
- uw_course/Utiles/randomColor.py,sha256=4zubPBcRxos5Rqb8O-ZmkYYKvzPP9NjSdzZwdTZOmy0,467
13
- uw_course-1.0.2.dist-info/LICENSE,sha256=3gvYdtz3_nCjhGpKAbUQzU1CT9anApYNOrn-bF6ZhI8,1073
14
- uw_course-1.0.2.dist-info/METADATA,sha256=ez_s3KIPEbWu4oZ1-G4d-dHklirhTc2ZWJLPNnqRwgA,2345
15
- uw_course-1.0.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
16
- uw_course-1.0.2.dist-info/entry_points.txt,sha256=KwZTcAbhGgjmTdkqwUtMDKzhZ1iqGY5OmaH6F7XNgRk,50
17
- uw_course-1.0.2.dist-info/top_level.txt,sha256=b760hy15dn_4qeUiKj9gQ8jnO9caaRoD-4ks28p81NY,10
18
- uw_course-1.0.2.dist-info/RECORD,,