noticecard 0.2.0__py3-none-any.whl → 0.2.1__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.
noticecard/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  """NoticeCard Server - A FastAPI-based card management system."""
2
2
 
3
- __version__ = "0.2.0"
3
+ __version__ = "0.2.1"
noticecard/app.py CHANGED
@@ -32,6 +32,10 @@ def create_app(db_path: str) -> FastAPI:
32
32
  """Create and configure FastAPI application."""
33
33
  global _session_maker, _db_path
34
34
 
35
+ # Check and migrate database if needed
36
+ from .migrations import check_and_migrate
37
+ check_and_migrate(db_path)
38
+
35
39
  _db_path = db_path
36
40
  engine = init_db(db_path)
37
41
  _session_maker = get_session_maker(engine)
@@ -81,7 +85,7 @@ def create_app(db_path: str) -> FastAPI:
81
85
  },
82
86
  "serverInfo": {
83
87
  "name": "noticecard",
84
- "version": "0.2.0"
88
+ "version": "0.2.1"
85
89
  }
86
90
  }
87
91
  }
noticecard/cli.py CHANGED
@@ -7,7 +7,7 @@ import uvicorn
7
7
 
8
8
 
9
9
  @click.group()
10
- @click.version_option(version="0.2.0")
10
+ @click.version_option(version="0.2.1")
11
11
  def main():
12
12
  """NoticeCard 服务端命令行工具"""
13
13
  pass
@@ -76,5 +76,25 @@ def init(work_dir: str):
76
76
  click.echo(f"数据库已初始化: {db_path}")
77
77
 
78
78
 
79
+ @main.command()
80
+ @click.option("--dir", "work_dir", default=".", help="工作目录")
81
+ def migrate(work_dir: str):
82
+ """迁移数据库到最新版本"""
83
+ work_path = Path(work_dir).resolve()
84
+ db_path = work_path / "noticecard.db"
85
+
86
+ if not db_path.exists():
87
+ click.echo(f"数据库不存在: {db_path}")
88
+ return
89
+
90
+ from .migrations import migrate_to_v2
91
+
92
+ try:
93
+ migrate_to_v2(str(db_path))
94
+ click.echo(f"✅ 数据库迁移成功: {db_path}")
95
+ except Exception as e:
96
+ click.echo(f"❌ 迁移失败: {e}", err=True)
97
+
98
+
79
99
  if __name__ == "__main__":
80
100
  main()
@@ -0,0 +1,84 @@
1
+ """Database migration utilities."""
2
+
3
+ import sqlite3
4
+ from pathlib import Path
5
+
6
+
7
+ def migrate_to_v2(db_path: str):
8
+ """Migrate database from v1 (desc1, desc2) to v2 (description)."""
9
+ conn = sqlite3.connect(db_path)
10
+ cursor = conn.cursor()
11
+
12
+ try:
13
+ # Check if we need to migrate
14
+ cursor.execute("PRAGMA table_info(cards)")
15
+ columns = [col[1] for col in cursor.fetchall()]
16
+
17
+ if 'description' in columns:
18
+ print("Database already migrated to v2")
19
+ return
20
+
21
+ if 'desc1' not in columns:
22
+ print("Database is already in correct format")
23
+ return
24
+
25
+ print("Migrating database to v2...")
26
+
27
+ # Create new table with description field
28
+ cursor.execute("""
29
+ CREATE TABLE cards_new (
30
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
31
+ title TEXT NOT NULL,
32
+ description TEXT,
33
+ created_at TIMESTAMP NOT NULL,
34
+ updated_at TIMESTAMP NOT NULL
35
+ )
36
+ """)
37
+
38
+ # Migrate data: combine desc1 and desc2 into description
39
+ cursor.execute("""
40
+ INSERT INTO cards_new (id, title, description, created_at, updated_at)
41
+ SELECT
42
+ id,
43
+ title,
44
+ CASE
45
+ WHEN desc1 IS NOT NULL AND desc2 IS NOT NULL THEN desc1 || '\n' || desc2
46
+ WHEN desc1 IS NOT NULL THEN desc1
47
+ WHEN desc2 IS NOT NULL THEN desc2
48
+ ELSE NULL
49
+ END as description,
50
+ created_at,
51
+ updated_at
52
+ FROM cards
53
+ """)
54
+
55
+ # Drop old table and rename new one
56
+ cursor.execute("DROP TABLE cards")
57
+ cursor.execute("ALTER TABLE cards_new RENAME TO cards")
58
+
59
+ # Create index
60
+ cursor.execute("CREATE INDEX ix_cards_title ON cards (title)")
61
+ cursor.execute("CREATE INDEX ix_cards_id ON cards (id)")
62
+
63
+ conn.commit()
64
+ print("Migration completed successfully!")
65
+
66
+ except Exception as e:
67
+ conn.rollback()
68
+ print(f"Migration failed: {e}")
69
+ raise
70
+ finally:
71
+ conn.close()
72
+
73
+
74
+ def check_and_migrate(db_path: str):
75
+ """Check database version and migrate if needed."""
76
+ if not Path(db_path).exists():
77
+ # New database, no migration needed
78
+ return
79
+
80
+ try:
81
+ migrate_to_v2(db_path)
82
+ except Exception as e:
83
+ print(f"Warning: Could not migrate database: {e}")
84
+ print("You may need to delete the old database and start fresh.")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: noticecard
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: NoticeCard server with RESTful API and web UI
5
5
  Author: NoticeCard Team
6
6
  License: MIT
@@ -0,0 +1,12 @@
1
+ noticecard/__init__.py,sha256=wx4Y1_IMhWSuRhcAJ8tUmdBV1YxQdEihvzS2TY4BDno,92
2
+ noticecard/app.py,sha256=HAg43uB0nS2aNViBq3eJFqTuY26s5O-_i5sGarHz4Bc,18746
3
+ noticecard/cli.py,sha256=rS0mlJ72TbBm2Y0sQH908nAiwiD8jnAu1wLV1Fj_Glc,3156
4
+ noticecard/migrations.py,sha256=YM8-CPZA-a2cTRCsBKP1ZljqXyTYLykrydxswOfP-9o,2731
5
+ noticecard/models.py,sha256=P6eirD7tVwOjAatA5MOZHDnjPr4-GJ_5zYCPMp0tFZs,1475
6
+ noticecard/schemas.py,sha256=FMEKNcnMR078F9T2hgEsygOVQgyJykHPRhlN_WSGU5A,1491
7
+ noticecard/templates.py,sha256=TCOr9Jv44I45GmrEPwQ_2JWRdXZNL-nRS6FKkU-65z4,19162
8
+ noticecard-0.2.1.dist-info/METADATA,sha256=mBQcsTDOELA1ACpHbqbCNI6KIAllbMNVV-aiv4Ulmgc,5553
9
+ noticecard-0.2.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
10
+ noticecard-0.2.1.dist-info/entry_points.txt,sha256=j-F8uQSatTV2uyMh0JM3iXjTX2PiTIHX5FozbGy-u1A,46
11
+ noticecard-0.2.1.dist-info/top_level.txt,sha256=WvuJAJMD8eTfRfGdeMAzSLXiv8UYjlfUBa5mw9g7Mqg,11
12
+ noticecard-0.2.1.dist-info/RECORD,,
@@ -1,11 +0,0 @@
1
- noticecard/__init__.py,sha256=PFY9KDi_UH6KUAAuZbDXq44gDZPqIrWV2cyYn2BoM-o,92
2
- noticecard/app.py,sha256=_poOGqlaFC3DF7lcisOoXxT_Xh0ZLE960v1kAGuDDzE,18617
3
- noticecard/cli.py,sha256=GToKNEStIEPLkgiWB61Q8Ro-U1_rVWds3bcoyPf8dCQ,2556
4
- noticecard/models.py,sha256=P6eirD7tVwOjAatA5MOZHDnjPr4-GJ_5zYCPMp0tFZs,1475
5
- noticecard/schemas.py,sha256=FMEKNcnMR078F9T2hgEsygOVQgyJykHPRhlN_WSGU5A,1491
6
- noticecard/templates.py,sha256=TCOr9Jv44I45GmrEPwQ_2JWRdXZNL-nRS6FKkU-65z4,19162
7
- noticecard-0.2.0.dist-info/METADATA,sha256=6iqnC1thb3hQZPUP_PxbIsnYmNHXxw_Ndf27ys9vsqk,5553
8
- noticecard-0.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
9
- noticecard-0.2.0.dist-info/entry_points.txt,sha256=j-F8uQSatTV2uyMh0JM3iXjTX2PiTIHX5FozbGy-u1A,46
10
- noticecard-0.2.0.dist-info/top_level.txt,sha256=WvuJAJMD8eTfRfGdeMAzSLXiv8UYjlfUBa5mw9g7Mqg,11
11
- noticecard-0.2.0.dist-info/RECORD,,