Updated htaccess to Apache 2.4 compat
[biaweb_qt.git] / main_window.py
1 # BiaWeb Website content manager (c) 2010 V.Harishankar
2 # Main Window class
3
4 import PyQt4
5 import sys
6
7 import ui_main_window
8 import site_configuration_dialog as scd
9 import category_dialog as catd
10 import article_dialog as artd
11 import templates_dialog as tpld
12 import generate_dialog as gend
13 import biaweb_db
14
15 class MainWindow (PyQt4.QtGui.QMainWindow, ui_main_window.Ui_MainWindow):
16 def __init__ (self):
17 PyQt4.QtGui.QMainWindow.__init__ (self)
18 self.setupUi (self)
19 self.current_db = None
20
21 # refresh the category list
22 def repopulate_categories (self):
23 recs = biaweb_db.get_categories (self.current_db)
24
25 # check with False because None is returned when no records exist
26 if recs is False:
27 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in getting the categories")
28 return False
29
30 self.categories.clear ()
31 for (id, name, desc, stub) in recs:
32 qrow = PyQt4.QtGui.QTreeWidgetItem ([str(id), str(name)])
33 self.categories.addTopLevelItem (qrow)
34
35 # return true when successful
36 return True
37
38 # refresh the articles list
39 def repopulate_articles (self, catid=None):
40 recs = biaweb_db.get_articles (self.current_db, catid)
41
42 # check with False because None is returned when no records exist
43 if recs is False:
44 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in getting the articles")
45 return False
46
47 self.articles.clear ()
48 for item in recs:
49 qrow = PyQt4.QtGui.QTreeWidgetItem ([str(item[0]), str(item[1])])
50 self.articles.addTopLevelItem (qrow)
51 # return true when successful
52 return True
53
54 # when the view is refreshed
55 def onViewRefresh (self):
56 if self.current_db is not None:
57 self.repopulate_categories ()
58 self.repopulate_articles ()
59
60 # when add article is triggered
61 def onArticleAdd (self):
62 if self.current_db is None:
63 PyQt4.QtGui.QMessageBox.critical (self, "Error",
64 "Cannot create article. You need to create or open a website first")
65 else:
66 catid = self.get_selected_item_id (self.categories)
67 # if no category is selected
68 if catid is None:
69 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No category selected for article")
70 return
71 artdlg = artd.ArticleDialog (self)
72 cats = biaweb_db.get_categories (self.current_db)
73
74 artdlg.populate_categories (cats, catid)
75
76 # if OK is pressed
77 if artdlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
78 title = str (artdlg.article_title.text ()).strip ()
79 keywords = str (artdlg.keywords.text ()).strip ()
80 summary = str (artdlg.summary.toPlainText ()).strip ()
81 content = str (artdlg.content.toPlainText ()).strip ()
82 cid, ok = artdlg.category.itemData (artdlg.category.currentIndex ()).toInt ()
83 # if catid is not an integer then abort
84 if not ok:
85 return
86 rating = artdlg.rating.value ()
87 stub = str (artdlg.stub.text ()).strip ()
88
89 ret = biaweb_db.create_article (self.current_db, title, summary, keywords, content, cid,
90 stub, rating)
91 if ret:
92 PyQt4.QtGui.QMessageBox.information (self, "Success", "Article successfully created")
93 self.repopulate_categories ()
94 self.repopulate_articles (catid)
95 else:
96 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in creating article")
97
98 # when edit article is triggered
99 def onArticleEdit (self):
100 if self.current_db is None:
101 PyQt4.QtGui.QMessageBox.critical (self, "Error",
102 "Cannot edit article. You need to create or open a website first")
103 else:
104 # get the selected article
105 artid = self.get_selected_item_id (self.articles)
106 catid = self.get_selected_item_id (self.categories)
107
108 # no article is selected
109 if artid is None:
110 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No article selected")
111 return
112 article = biaweb_db.get_article (self.current_db, artid)
113 # if article cannot be read
114 if not article:
115 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in reading article")
116 return
117 artdlg = artd.ArticleDialog (self)
118
119 artdlg.article_title.setText (article[1])
120 artdlg.summary.setPlainText (article[2])
121 artdlg.keywords.setText (article[3])
122 artdlg.content.setPlainText (article[4])
123 # populate category combo box and set active category to the article's category
124 cats = biaweb_db.get_categories (self.current_db)
125 artdlg.populate_categories (cats, article[7])
126 artdlg.stub.setText (article[8])
127 artdlg.rating.setValue (article[9])
128
129 # ok is pressed
130 if artdlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
131 title = str (artdlg.article_title.text ()).strip ()
132 summary = str (artdlg.summary.toPlainText ()).strip ()
133 keywords = str (artdlg.keywords.text ()).strip ()
134 content = str (artdlg.content.toPlainText ()).strip ()
135 cid, ok = artdlg.category.itemData (artdlg.category.currentIndex()).toInt ()
136 # if cat id is not an integer
137 if not ok:
138 return
139 rating = artdlg.rating.value ()
140 stub = str (artdlg.stub.text ()).strip ()
141 ret = biaweb_db.update_article (self.current_db, artid, title,
142 summary, keywords, content, cid, stub, rating)
143 if ret:
144 PyQt4.QtGui.QMessageBox.information (self, "Success", "Article successfully updated")
145 self.repopulate_articles (catid)
146 else:
147 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in updating article")
148
149 # when delete article is triggered
150 def onArticleDelete (self):
151 if self.current_db is None:
152 PyQt4.QtGui.QMessageBox.critical (self, "Error",
153 "Cannot delete article. You need to create or open a website first")
154 else:
155 # get the selected article
156 artid = self.get_selected_item_id (self.articles)
157 catid = self.get_selected_item_id (self.categories)
158 if artid is None:
159 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No article selected")
160 return
161 # get confirmation on delete
162 flag = PyQt4.QtGui.QMessageBox.question (self, "Confirm",
163 "Are you sure you wish to delete the selected article?",
164 PyQt4.QtGui.QMessageBox.Yes, PyQt4.QtGui.QMessageBox.No)
165 # confirmed
166 if flag == PyQt4.QtGui.QMessageBox.Yes:
167 ret = biaweb_db.delete_article (self.current_db, artid)
168 if not ret:
169 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in deleting article")
170 else:
171 self.repopulate_articles (catid)
172
173 # when category item is activated
174 def onCategoryItemActivated (self):
175 self.onCategoryEdit ()
176
177 # when article item is activated
178 def onArticleItemActivated (self):
179 self.onArticleEdit ()
180
181 # when item selection is changed in categories tree widget
182 def onCategorySelectionChanged (self):
183 if self.current_db is not None:
184 catid = self.get_selected_item_id (self.categories)
185 self.repopulate_articles (catid)
186
187 # when configuration menu is triggered
188 def onConfiguration (self):
189 if self.current_db is None:
190 PyQt4.QtGui.QMessageBox.critical (self, "Error",
191 "Cannot edit configuration. You need to create or open a website first")
192 else:
193 dlg = scd.SiteConfigDialog (self)
194 configs = biaweb_db.get_configuration (self.current_db)
195
196 if not configs:
197 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in reading configuration")
198 return
199
200 # set the data
201 dlg.site_url.setText (configs[0])
202 dlg.site_title.setText (configs[1])
203 dlg.keywords.setText (configs[2])
204 dlg.description.setPlainText (configs[3])
205 dlg.num_rss_items.setValue (configs[4])
206 dlg.destination.setText (configs[5])
207 dlg.copyright.setText (configs[6])
208
209 if (dlg.exec_ () == PyQt4.QtGui.QDialog.Accepted):
210 # if accepted, get the data and store in database
211 site_title = str (dlg.site_title.text ()).strip ()
212 site_url = str (dlg.site_url.text ()).strip ()
213 keywords = str (dlg.keywords.text ()).strip ()
214 destination = str (dlg.destination.text ()).strip ()
215 description = str (dlg.description.toPlainText ()).strip ()
216 num_rss = dlg.num_rss_items.value ()
217 copyright = str (dlg.copyright.text ()).strip ()
218 # database update
219 flag = biaweb_db.set_configuration (self.current_db, site_title, site_url, keywords, description,
220 copyright, num_rss, destination)
221 if not flag:
222 PyQt4.QtGui.QMessageBox.critical (self, "Error",
223 "SQLite 3 error in updating configuration")
224
225 # when templates menu is triggered
226 def onTemplates (self):
227 if self.current_db is None:
228 PyQt4.QtGui.QMessageBox.critical (self, "Error",
229 "Cannot edit templates. You need to create or open a website first")
230 else:
231 tdlg = tpld.TemplatesDialog (self, self.current_db)
232 tdlg.exec_ ()
233
234 # function to get the category or article ID from current selected item in a tree widget
235 def get_selected_item_id (self, twidget):
236 selitems = twidget.selectedItems ()
237 if selitems:
238 # get the first column data as integer
239 selindex = selitems[0].data(0, 0).toInt ()[0]
240 return selindex
241 else:
242 return None
243
244 # category edit action
245 def onCategoryEdit (self):
246 # if no database is open
247 if self.current_db is None:
248 PyQt4.QtGui.QMessageBox.critical (self, "Error",
249 "Cannot edit category. You need to create or open a website first")
250 # database is open
251 else:
252 catid = self.get_selected_item_id (self.categories)
253 # if no category is selected, display an error
254 if catid is None:
255 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No category selected")
256 # category is selected
257 else:
258 cat = biaweb_db.get_category (self.current_db, catid)
259 # if the category cannot be retrieved from database
260 if not cat:
261 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in reading category")
262 return
263
264 # set the data in the dialog
265 dlg = catd.CategoryDialog (self)
266 dlg.category_name.setText (cat[1])
267 dlg.category_desc.setText (cat[2])
268 dlg.category_stub.setText (cat[3])
269
270 # if accepted
271 if dlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
272 category_name = str (dlg.category_name.text ()).strip ()
273 category_desc = str (dlg.category_desc.text ()).strip ()
274 category_stub = str (dlg.category_stub.text ()).strip ()
275
276 ret = biaweb_db.update_category (self.current_db,
277 catid, category_name, category_desc, category_stub)
278 if ret:
279 PyQt4.QtGui.QMessageBox.information (self, "Success", "Category successfully updated")
280 self.repopulate_categories ()
281 else:
282 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in updating category")
283
284
285 # category delete action
286 def onCategoryDelete (self):
287 # if there is no database
288 if self.current_db is None:
289 PyQt4.QtGui.QMessageBox.critical (self, "Error",
290 "Cannot delete category. You need to create or open a website first")
291 else:
292 # get the selected category
293 catid = self.get_selected_item_id (self.categories)
294 if catid is None:
295 PyQt4.QtGui.QMessageBox.critical (self, "Error", "No category selected")
296 # category is selected
297 else:
298 # get confirmation first
299 flag = PyQt4.QtGui.QMessageBox.question (self, "Confirm",
300 "This will delete the category and all associated articles. Are you sure you wish to continue?",
301 PyQt4.QtGui.QMessageBox.Yes, PyQt4.QtGui.QMessageBox.No)
302 # if confirmed
303 if flag == PyQt4.QtGui.QMessageBox.Yes:
304 ret = biaweb_db.remove_category (self.current_db, catid)
305 if not ret:
306 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in deleting category")
307 else:
308 self.repopulate_categories ()
309 self.repopulate_articles ()
310
311 # category add action
312 def onCategoryAdd (self):
313 # if there is no database
314 if self.current_db is None:
315 PyQt4.QtGui.QMessageBox.critical (self, "Error",
316 "Cannot add category. You need to create or open a website first")
317 else:
318 # show the category add dialog
319 dlg = catd.CategoryDialog (self)
320 # if OK button is pressed
321 if dlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
322 cat_name = str (dlg.category_name.text ()).strip ()
323 cat_desc = str (dlg.category_desc.text ()).strip ()
324 cat_stub = str (dlg.category_stub.text ()).strip ()
325 ret = biaweb_db.create_category (self.current_db, cat_name, cat_desc, cat_stub)
326 if ret:
327 PyQt4.QtGui.QMessageBox.information (self, "Success", "Category successfully created")
328 self.repopulate_categories ()
329 self.repopulate_articles ()
330 else:
331 PyQt4.QtGui.QMessageBox.critical (self, "Error", "SQLite 3 error in creating category")
332
333 # file open menu is clicked
334 def onFileOpen (self):
335 filename = PyQt4.QtGui.QFileDialog.getOpenFileName (self, "Open Site Database")
336 if filename:
337 self.current_db = str (filename)
338
339 # added to check whether categories are loaded successfully or not
340 # if not, then reset the current_db to None
341 loaded_cats = self.repopulate_categories ()
342 loaded_arts = self.repopulate_articles ()
343 # if failed in loading either categories or articles (note: checking against
344 # False and not None)
345 if loaded_cats is False or loaded_arts is False:
346 self.current_db = None
347 PyQt4.QtGui.QMessageBox.critical (self, "Error",
348 "SQLite 3 error in loading site database. This appears to be an invalid BiaWeb database")
349 else:
350 # set the window title to the database
351 self.setWindowTitle ("BiaWeb - " + self.current_db)
352
353
354 # file new menu is clicked
355 def onFileNew (self):
356 # show the site configuration dialog to get the new site details
357 dlg = scd.SiteConfigDialog (self)
358 # if OK button is pressed
359 if dlg.exec_ () == PyQt4.QtGui.QDialog.Accepted:
360 site_title = str (dlg.site_title.text ()).strip ()
361 site_url = str (dlg.site_url.text ()).strip ()
362 keywords = str (dlg.keywords.text ()).strip ()
363 destination = str (dlg.destination.text ()).strip ()
364 description = str (dlg.description.toPlainText ()).strip ()
365 num_rss = dlg.num_rss_items.value ()
366 copyright = str (dlg.copyright.text ()).strip ()
367
368 savefilename = PyQt4.QtGui.QFileDialog.getSaveFileName (self, "Save site database to")
369
370 if savefilename:
371 self.current_db = str (savefilename)
372 self.setWindowTitle ("BiaWeb - " + self.current_db)
373 flag = biaweb_db.create_db (self.current_db, site_title, site_url, keywords, description,
374 copyright, num_rss, destination)
375 if flag:
376 PyQt4.QtGui.QMessageBox.information (self, "Success",
377 "New site db successfully created")
378 self.articles.clear ()
379 self.categories.clear ()
380 else:
381 PyQt4.QtGui.QMessageBox.critical (self, "Error", "System or SQLite 3 error in creating database")
382
383 # when generate site menu is triggered
384 def onGenerateSite (self):
385 if self.current_db is None:
386 PyQt4.QtGui.QMessageBox.critical (self, "Error",
387 "Cannot generate site. You need to create or open a website first")
388 else:
389 # run the generate site dialog
390 gendlg = gend.GenerateDialog (self, self.current_db)
391 gendlg.exec_ ()
392
393 # about menu is triggered
394 def onAbout (self):
395 PyQt4.QtGui.QMessageBox.about (self, "BiaWeb Qt",
396 "<b>A static website/weblog content management system</b><br /><br />\
397 Copyright &copy; 2010 <a href=\"http://www.harishankar.org\">Harishankar</a><br />\
398 Licensed under GNU/GPL v3")
399
400 # file quit is clicked
401 def onFileQuit (self):
402 sys.exit (0)