Implemented additional files/folders adding
[biaweb_qt.git] / biaweb_exporter.py
1 # BiaWeb Website content manager (c) 2010 V.Harishankar
2 # Site exporter/generator class
3
4 import os
5 import os.path
6 import sys
7 import time
8 import sqlite3
9 import string
10 import shutil
11 import biaweb_db
12
13 # to format the best rated articles in a HTML link list
14 def html_format_best_rated (best_rated):
15 items = [ "<ul>\n", ]
16 for art in best_rated:
17 # art[13] is category stub, art[8] is article stub
18 # thus forming the relative url as Category/Article.html
19 str_art = '<li><a href="' + art[13] + '/' + art[8] + '.html">' + art[1] + '</a></li>\n'
20 items.append (str_art)
21 items.append ("</ul>\n")
22 str_items = "".join (items)
23 return str_items
24
25 # to format categories in a HTML link list
26 def html_format_categories (cats):
27 items = [ "<ul>\n", ]
28 for cat in cats:
29 # cat[3] is category stub and cat[1] is category name
30 str_cat = '<li><a href="' + cat[3] + '/">' + cat[1] + '</a></li>\n'
31 items.append (str_cat)
32 items.append ("</ul>\n")
33 str_items = "".join (items)
34 return str_items
35
36 # to convert a rating number into rating images out of 10 stars
37 def html_format_rating (rating):
38 items = []
39 # if -1 then return unrated as the text
40 if rating == -1:
41 return "unrated"
42 # fill up the number of stars for the rating
43 for i in range (rating):
44 items.append ('<img src="star.gif" alt="*" />')
45 # fill up remaining slots (of 10) with grey stars
46 for i in range (10 - rating):
47 items.append ('<img src="star-grey.gif" alt="-" />')
48
49 rating_str = "".join (items)
50 return rating_str
51
52 # function to copy additional files and folders to the destination path
53 def copy_files_folders (conf, files_to_copy, folders_to_copy):
54 # create the cgi-bin directory and try to copy search.py into the destination directory if possible
55 # otherwise user must copy it manually
56 search_script_path = os.path.join (sys.path[0], "search.py")
57 if os.path.exists (search_script_path):
58 try:
59 os.mkdir (os.path.join (conf[5], "cgi-bin"))
60 shutil.copy2 (search_script_path, os.path.join(conf[5], "cgi-bin"))
61 except IOError, OSError:
62 return False
63
64 # try to copy the star rating images to destination directory if possible
65 # otherwise user must copy it manually
66 rating_img_star = os.path.join (sys.path[0], "star.gif")
67 rating_img_greystar = os.path.join (sys.path[0], "star-grey.gif")
68 if os.path.exists (rating_img_star):
69 try:
70 shutil.copy2 (rating_img_star, conf[5])
71 except IOError, OSError:
72 return False
73 if os.path.exists (rating_img_greystar):
74 try:
75 shutil.copy2 (rating_img_greystar, conf[5])
76 except IOError, OSError:
77 return False
78
79 # additional files to copy
80
81 # first copy files
82 # check if files to copy is not empty
83 if files_to_copy <> []:
84 for src, dest in files_to_copy:
85 # get full path from relative path in dest
86 full_dest = os.path.join (conf[5], dest)
87 try:
88 shutil.copy2 (src, full_dest)
89 except IOError, OSError:
90 return False
91
92 # additional folders to copy
93
94 # now copy the folders
95 if folders_to_copy <> []:
96 for src, dest in folders_to_copy:
97 # get full path from relative path in dest
98 full_dest = os.path.join (conf[5], dest)
99 try:
100 shutil.copytree (src, full_dest)
101 except IOError, OSError:
102 return False
103
104 # finally return true
105 return True
106
107
108
109 # function to generate article pages
110 def generate_article_pages (dbname, conf, templates, category_str, bestrated_str):
111 # main template
112 tpl_main = string.Template (templates[0][1])
113 # article template
114 tpl_articlebit = string.Template (templates[1][1])
115
116 # get all articles from the database
117 articles = biaweb_db.site_articles (dbname)
118 if articles == False:
119 return
120
121 # walk through each article and generate the file in the appropriate category
122 # folder
123 for art in articles:
124 art_cdate = time.ctime (art[5])
125 art_mdate = time.ctime (art[6])
126 rating_str = html_format_rating (art[9])
127 # now build the article from the article bit template
128 article_str = tpl_articlebit.safe_substitute (article_title = art[1],
129 article_cdate = art_cdate,
130 article_mdate = art_mdate,
131 rating = rating_str,
132 article_contents = art[4])
133
134 # now build the article page
135 articlepage_str = tpl_main.safe_substitute (site_title = conf[1],
136 site_url = "http://" + conf[0],
137 meta_keywords = art[3],
138 meta_description = art[2],
139 page_title = conf[1],
140 page_desc = conf[3],
141 contents_bit = article_str,
142 list_of_categories = category_str,
143 list_best_rated = bestrated_str,
144 copyright = conf[6])
145 # write to the article file
146 try:
147 farticle = open (os.path.join (conf[5], art[13], art[8] + ".html"), "w+")
148 farticle.write (articlepage_str)
149 except OSError, IOError:
150 return False
151
152 # finally return true
153 return True
154
155 # function to generate category directories and indices
156 def generate_category_indices (dbname, conf, templates, category_str, bestrated_str, category_list):
157 # main template
158 tpl_main = string.Template (templates[0][1])
159 # table bit
160 tpl_tablebit = string.Template (templates[3][1])
161 # table row bit
162 tpl_trowbit = string.Template (templates[4][1])
163
164 # run through each category and generate category index page
165 for cat in category_list:
166 try:
167 # create the category directory
168 os.mkdir (os.path.join (conf[5], cat[3]))
169 except IOError, OSError:
170 return False
171
172 # now get the list of articles for the specified category
173 articles_list = biaweb_db.site_articles (dbname, cat[0])
174 if articles_list == False:
175 return False
176
177 tableitems = []
178 # run through the list of articles in category
179 for art in articles_list:
180 url = art[13] + "/" + art[8] + ".html"
181 creattime = time.ctime (art[5])
182 rating_str = html_format_rating (art[9])
183 # now build the table rows for each article
184 tableitem_str = tpl_trowbit.safe_substitute (article_url = url,
185 title = art[1],
186 created = creattime,
187 rating = rating_str)
188 tableitems.append (tableitem_str)
189 # generate the rows as a string
190 tablerows_str = "".join (tableitems)
191
192 # now create the page template
193 table_str = tpl_tablebit.safe_substitute (category_title = cat[1],
194 category_desc = cat[2],
195 table_rows = tablerows_str)
196
197 # now create the index page
198 categoryindex_str = tpl_main.safe_substitute (site_title = conf[1],
199 site_url = "http://" + conf[0],
200 meta_keywords = conf[2],
201 meta_description = cat[2],
202 page_title = conf[1],
203 page_desc = conf[3],
204 contents_bit = table_str,
205 list_of_categories = category_str,
206 list_best_rated = bestrated_str,
207 copyright = conf[6])
208
209 # now write to Category/index.html
210 try:
211 fcatindex = open (os.path.join (conf[5], cat[3], "index.html"), "w+")
212 fcatindex.write (categoryindex_str)
213 fcatindex.close ()
214 except OSError, IOError:
215 return False
216
217 # finally return true
218 return True
219
220 # function to generate main index file and stylesheet
221 def generate_home_page (dbname, conf, templates, category_str, bestrated_str):
222 # main template
223 tpl_main = string.Template (templates[0][1])
224 # index bit
225 tpl_indexbit = string.Template (templates[6][1])
226 # news bits
227 tpl_newsbit = string.Template (templates[2][1])
228
229 # get the latest articles - conf[4] is num of rss entries to be used also
230 latest_arts = biaweb_db.site_latest_articles (dbname, conf[4])
231 if latest_arts == False:
232 return False
233
234 news_items = []
235
236 # Run through the latest articles
237 # for the num of latest news items on index
238 for art in latest_arts:
239 # url is Category/Article.html
240 url = art[13] + "/" + art[8] + ".html"
241 # art[5] is creation time
242 strdate = time.ctime (art[5])
243 # now populate the template variables. art[1] is title, art[2] is summary
244 strnews = tpl_newsbit.safe_substitute (news_title = art[1],
245 news_link = url,
246 news_datetime = strdate,
247 news_description = art[2]
248 )
249 news_items.append (strnews)
250 # now convert it into a string
251 newsbit_str = "".join (news_items)
252
253 # now populate the index template
254 indexbit_str = tpl_indexbit.safe_substitute (site_name = conf[1],
255 news_updates = newsbit_str
256 )
257 # now populate the main page template
258 main_str = tpl_main.safe_substitute (site_title = conf[1],
259 site_url = "http://" + conf[0],
260 meta_keywords = conf[2],
261 meta_description = conf[3],
262 page_title = conf[1],
263 page_desc = conf[3],
264 contents_bit = indexbit_str,
265 list_of_categories = category_str,
266 list_best_rated = bestrated_str,
267 copyright = conf[6])
268
269 # write the index.html file in the destination directory
270 try:
271 findex = open (os.path.join (conf[5], "index.html"), "w+")
272 findex.write (main_str)
273 findex.close ()
274 except IOError, OSError:
275 return False
276
277 # write the style.css file in the destination directory
278 try:
279 fstyle = open (os.path.join (conf[5], "style.css"), "w+")
280 fstyle.write (templates[5][1])
281 fstyle.close ()
282 except IOError, OSError:
283 return False
284
285 return True
286
287 # superfunction to generate the site
288 def generate_site (dbname, files_to_copy, folders_to_copy, search_type_full=True):
289 # get the configuration
290 conf = biaweb_db.get_configuration (dbname)
291 # get the templates
292 tpls = biaweb_db.get_templates (dbname)
293
294 # get the list of categories
295 cats = biaweb_db.get_categories (dbname)
296 # cannot get categories return false
297 if cats == False:
298 return False
299
300 # format the categories as a html bulleted list
301 cats_str = html_format_categories (cats)
302
303 # get the best rated articles
304 best_rated = biaweb_db.site_get_bestrated (dbname)
305 # if cannot retrieve
306 if best_rated == False:
307 return False
308 # format the best rated articles as a html bulleted list
309 best_rated_str = html_format_best_rated (best_rated)
310
311 # remove the destination tree and recreate it
312 try:
313 if os.path.exists (conf[5]):
314 shutil.rmtree (conf[5])
315 os.mkdir (conf[5])
316 except OSError:
317 return False
318
319 # generate the index page including style sheet
320 ret = generate_home_page (dbname, conf, tpls, cats_str, best_rated_str)
321 if ret == False:
322 return False
323
324 # generate the category directories and indices
325 ret = generate_category_indices (dbname, conf, tpls, cats_str, best_rated_str, cats)
326 if ret == False:
327 return False
328
329 # generate the article pages
330 ret = generate_article_pages (dbname, conf, tpls, cats_str, best_rated_str)
331 if ret == False:
332 return False
333
334 # copy other files/folders into the destination path
335 ret = copy_files_folders (conf, files_to_copy, folders_to_copy)
336 if ret == False:
337 return False
338
339 # finally when all is successfully done return true
340 return True