# Photo Photograph / Video Portal Generator # (c) 2000-2011 Sandipan Gangopadhyay strCodeVersion = "53.0" # ========================================================================== WEBSITE PUBLISHER ===================================================================== # Next: XML processing for YouTube, titles, inserts, using namespaces, Password protected pages, process images to allow native to be opened on click, integration of story-writer version and auto-propagation scripts, fix emailer, RSS viewer portlet, emailer for pictures # Next: New slideshow # Next: Remove PIL from emailers # Next: Integrate album with Android App # Version 53.0 of September 24, 2011 - Banner Changes through slideshow # Version 52.0 of July 08, 2011 - Google Translate on the footer # Version 51.0 of March 20, 2011 - Breadcrumbs have backgrounds # Version 51.0 of March 20, 2011 - Page Contents (Titles), emailer # Version 50.0 of March 12, 2011 - Jump to page top from each section header and a section at the bottom with a list of child pages # Version 49.0 of March 05, 2011 - Navigation buttons beside the bread crumbs, Site Map now refers to bread crumbs as page hierarchy, Definable page background images or color, CSS3 stretching for background images # Version 48.0 of February 26, 2011 - Site Map to also list bread crumbs (for a sense of the hierarchy) # Version 47.0 of February 23, 2011 - Do not put
when content lines end with '>', meaning that when the content is HTML # Version 46.0 of February 20, 2011 - Current Page's Menu item's "under-bar" starts RED once the new page loads # Version 45.0 of February 16, 2011 - Auto scroller and Private folders (for password protect, etc.) # Version 40.0 - 44.0 of January 12, 2011 - Look and feel: Blue lines look, relative links to banners and icons, fixed a ton of HTML4.01 and CSS bugs, floating reading panel # Version 40.0 of January 12, 2011 - Look and feel: Side panels # Version 39.0 of January 09, 2011 - Consumes Auto Generated content such as SandhirImagePublisherV27 # Version 38.0 of December 05, 2010 - HTML and CSS bugs fixed at Home Page Level # Version 37.0 of December 05, 2010 - Integrated Google Search # Version 36.0 of November 28, 2010 - Changes the banner image onclick and a fix for the bug on EmailTheWeb integration (was sending out the parent page) # Version 35.0 of November 28, 2010 - removed Album publisher code # Version 34.0 of November 27, 2010 - Site Publisher - All works, but HTML bugs remaining ... some of them need style refs and some are simply not bugs # Versions all the way up to ... # Version 26.0 of November 21, 2010 - Site Publisher # ========================================================================== ALBUM PUBLISHER ===================================================================== # Version 24.0 of July 03, 2009 - Folder SCP AND Twitter Interface # Version 23.0 of May 22, 2009 - Facebook Share Partner Preview meta-data in thumbnail pages, inclusion of special YouTube account credentials in ALT text, integration with FB (through a share link!) and starting on Auto-SCP to the web server # Version 22.0 of April 30, 2009 - YouTube integration for Videos through Google Data API # Version 21.0 of January 18, 2009 - Corel Painter writes JPG, not PNG ... so we put in a converter for these. The JPG becomes a native file; Shuts off extra stuff by default # Version 20.0 of January 13, 2009 - Reads key super album related info (local and web paths) from a config file so that the same prog can be used for all albums; Common eMailer; # Version 19.0 of January 10, 2009 - Can publish pictorial stories # Version 18.0 of December 25, 2008 - Representative photo from the album is shown with the album name in the Album List page # Version 17.0 of May 11, 2008 - Album names are split up so that they are more reader friendly AND more search-engine friendly (Longwood Gardens Visit instead of LongwoodGardensVisit) # Version 16.1 of May 1, 2008 - Disabled Image.Keys because for Canon Cameras, EXIF values were binary and causing client side JS to fail (unterminated string literals) # Version 16.0 of September 4, 2007 - On WinVistaUlti on Node18, on Python-2.5.1, had to fix spl char on Sandhir # Version 15.0 of December 11, 2006 - TouchMode ... longstanding need to not reprocess existing folders # Version 10.0 of May 23, 2006 - Working on including GIF animated version of video thumbnails for .AVI and .MPEG # Version 9.0 of April 18 - May 15, 2006 - Handling Videos in thumbnail page AND emailing out photographs/videos # Version 8.0 of January 2, 2006 - Touch-file concept for folders already processed # Version 7.2 of April 23, 2005 - Multi-depth folder bugfixes # Version 7.1 of October 8, 2004 - Album title and caption on Thumbnails Page # Version 7.0 of October 8, 2004 - Thumbnails Page (The C8080 came in today) completed in a day! # Version 6.0 of June 17, 2004 - Reverse sort order version # Version 5.0 of August 03, 2003 - Top level slide show version - has not been implemented # Version 4.0 of May 26 - June 07, 2003 - Slide show version # Version 3.0 of May 26, 2003 requires ExifTags Utility to read JPEG file properties # Version 2.0 of May 25, 2003 requires Python Image Library Version 1.1.4 for Python Version 2.2 # Version 1.0 on Python Version 2.2 # Based on Reporter Version 3.8 of 2002 (dates of modification, etc added) # Version broken off for the Galaxy Svc Portal Version 3.7.2 of 2002.04.08 # Previous Version 3.7 of 2000.03.22 # MODULE IMPORT import time, os, Image, urllib, string, math, os.path, calendar, gdata.youtube, gdata.youtube.service, sys, rfc822 import xml.etree.ElementTree as ET # GLOBAL VARIABLE DECLARATION strPortalPage = "Page.html" # Name of the List Page that lists all albums strConfigFile = "configuration.txt" # Name of the file, which if present will be read and values used to override some of the global declarations here lstConfigTypes = ["strReport1Path", "strReport3Path", "strAlbumPath", "strWebsitePath", "binStory", "binTouchMode", "binEmbedVideo", "intLogLevel", "binYouTube", "binYTPrivate", "strYTDeveloperKey", "strYTClientId", "strYTEmail", "strYTPwd", "strYTSource"] strThumbsPage = "thumbs.html" # Name of the Thumbnail Page for each album strDescriptionFileName = "111-FileDescription.txt" # File in which description of the image/video can be stored. If present, it will be added to the caption for that image to be brought up along with JFIF info strAlbumIconFileName = "111-AlbumIcon.txt" # File in which the file name of the image is stored that will represent the album in the album list page. In its absence, the first image in the album will be selected strFolderProcessedMarker = "x-FolderProcessed.txt" # Flag that the folder has been processed - Deprecated? strVideoProcessingFolder = "VideoExtraction" # Folder where all the working files for video extraction are temporarily stored strReport1Path = "Images" # Folder in the album where all the assets are strReport2Path = "Videos" # Folder in the album where all the assets are - Not used; Images hold both images and videos strReport3Path = "OccasionallyImmortal" # Folder in the album where all the assets are # strAlbumPath = "E:\\Data\\Reporter\\reporter" # Where on the computer where this program is being run is this album - Windows FS - the Prog will first chdir to it strAlbumPath = "E:\\Data\\Reporter\\reporter\\PriorVersions\\CodeBackups\\reporterV220" # strWebsitePath = "/family/doc-rep/certificates2" # Where in the website is going to be this album or story - Unix FS - We need to send this to the Emailer ... we need to make this change in the future # strWebsitePath = "/family/albumer2" # Where in the website is going to be this album or story # strWebsitePath = "/family/albumer3" # Where in the website is going to be this album or story strWebsitePath = "/links/stories/immortal/reporterV190" # Where in the website is going to be this album or story strSmallDir = "Smalls" # Folder in each album where small version of images are stored strThumbsDir = "Thumbnails" # Folder in each album where thumbnail version of images are stored strTemplatePath = "report-templates/" # Folder in the super album where web-page templates are stored strTempFile = "xxx.txt" # Used for temporarily storing information about images and videos lstStyleFiles = ["album.html", "dashstyle.css", "image2.jpg", "xmp1.jpg"] # Contents of Style Folder in each album strThumbBkgrd = "./style/crinklepaper.jpg" # Where the background for thumbnails for List Page is stored strEmailIcon = "../../../Icons/email018.gif" # Icon for Email button used to pop up form page to send images by email strThumbFileExt = ".jpg" # Default thumbnail type ... videos use .gif for the animated icons strReadError = "---ERROR---" # Value when a file reading has resulted in an error binEmbedVideo = 0 # Indicates whether we embed video in the thumbnail page or embed the animated gif version (video is NOT advised ... large vids will take a long time for the album page to load) binTouchMode = 1 # Starts V15.0 - Whether folders without touchfiles should not be processed - saves a TON of time ... the List Page is regenrated and also each album page, but the images, videos are not even opened strTouchFile = strThumbsPage # Only if this file exists in the album folder when the binTouchMode is true, the folder is fully processed ... currently set to the Thumbnail Page binYouTube = 1 # binYouTube when true will result in the video files with a corresponding .ytb file being uploaded to youtube if possible binYouTubePrivate = 1 # If true, will result in the video being uploaded into the private area in YouTube strYouTubeCredsFile = "YouTubeCreds.txt" # File with YouTube credentials strYouTubeMarkerFileExt = "ytb" # File extension for file that signifies that the video should be uploaded to YouTube and later, contains YouTube upload data # INITIALIZE LOG LEVEL intLogLevel = 5 # RECURSION HANDLERS AND GENERAL GLOBAL VARIABLE / ITERATOR INITIALIZATION (We have minimized these to ensure the program can be broken up into classes later and reduce cohesion) lstOuterFolderItems = [] # Do not remember intFolderDepth = 0 # Depth of recursion into nested album folders strSection = "" # The section of the List Page being built recursively lstAlbums = [] # List of albums within the Super Album intTotalItems = 0 # Total number of digital assets hosted # GLOBAL SETTINGS intImageWidth = 600 # Width in pixels for the width of an image. Used where? intImageHeight = 500 # Height in pixels for the width of an image. Used where? intSmallWidth = 640 # Width in pixels for the width of the small version of an image intSmallHeight = 480 # Height in pixels for the width of the small version of an image intThumbWidth = 240 # Width in pixels for the width of the thumbnail version of an image intThumbHeight = 180 # Height in pixels for the width of the thumbnail version of an image intThumbsWidthwise = 5 # The number of thumbnails across the width of a page intExtractsPerVideo = 5 # The number of frames extracted from a video file for stitching together in the Thumbnail GIF intIntervalsInExtracts = 100 # mSeconds # Interval between frames (not really used?) intExtracts2PerVideo = 30 # The number of frames extracted from a video file for stitching together in the Small / Snaps GIF intIntervalsInExtracts2 = 20 # mSeconds # Interval between frames (not really used?) # STORY PUBLISHER VARIABLE DECLARATION binStory = 0 # True indicates that the program should process a pictorial story, not an album - The Story Switch intThumbShadowOffset = 5 # The depth of shadow for the thumbnails and narrative panels strResearchDir = "Data" # Folder in which data, items, sketches, etc about the story plates are stored strPlateImageTypeExt = "png" # We are using PNGs for story images as we are concerned about IPR liabilities associated with JPGs and GIFs strNativeExt = "eps" # Extension / type of the actual native artwork file ... EPS or SVG ... vector graphics supported by InkScape, Adobe Illustrator, Corel Painter strPlatePrefix = "plate" # Each story picture starts with this prefix # Icon Files strSmllIcon = "../../Icons/Picture.png" # Link to the small Version of the PNG - Painting strLargIcon = "../../Icons/Picture.png" # Link to the native, large Version of the PNG - Painting strNatvIcon = "../../Icons/gear.gif" # Link to the native Version of the file - Gears strItemIcon = "../../Icons/search.png" # Link to research files and items (photographs, docs) - Magnifying Glass strLinkIcon = "../../Icons/link.png" # Link to links - Chain strIdeaIcon = "../../Icons/bulb.png" # Link to thoughts, discussions and ideas - A light bulb lstNarrativePrefixes = ["Narrative: ", "Dialogue: ", "Item: ", "Link: ", "Discussion: "] # Prefixes in Narrative Files lstNativeGraphicsExt = ["ai", "svg", "rif", "eps", "jpg"] # Covers Adobe Illustrator, Inkscape, Corel Painter, Encapsulated PostScript # YOUTUBE UPLOAD DECLARATIONS binYouTube = 1 # binYoutube when true will upload all videos unless each video's .ytb file has "DONT UPLOAD" in it to YouTube binYTPrivate = 1 # binYTPrivate when true will upload as a Private video (Dhirja's wish) strYTDeveloperKey = 'XXX' # YouTube Developer Credentials ... Not published here, of course! strYTClientId = 'XXX' # ID of the client (this app) strYTEmail = 'XXX' # User ID of the account strYTPwd = 'XXX' # Pwd of the account strYTSource = 'Sandipans Album Publisher' # Identification of the Application doing the upload (this app) strYTVideoID = 'xxx' # Blank YouTube Video ID strYTBFileExt = '.ytb' # YouTube Information File Extension (Created for each video that is uploaded) strYTBFolderFlagFileName = "dontupload.ytb" # If a folder has a file of this name in it, videos in the folder are NOT uploaded to YouTube # UTILITY TO WRITE A STRING TO THE ALBUM LIST PAGE def fnWrite(strWrite): return try: flWriter = open(strPortalPage, "a") flWriter.write(strWrite) flWriter.close() except: print "Oops! Could not write %s" % strWrite pass return # UTILITY TO WRITE A STRING TO A FILE def fnFileWrite(strFile, strWrite, chrMode): try: flWriter = open(strFile, chrMode) flWriter.write(strWrite) flWriter.close() except: print "Oops! Could not write to file [%s]: %s" % (strFile, strWrite) pass return def fnFileWriteRaw(strFile, strWrite, chrMode): flWriter = open(strFile, chrMode) flWriter.write(strWrite) flWriter.close() return # UTILITY TO READ A FILE INTO A STRING def fnRead(strRead): try: flReader = open(strRead, "r") strReader = flReader.read() flReader.close() except: # print "Oops! Could not read %s" % strRead strReader = strReadError return strReader # UTILITY TO READ A FILE INTO A LIST OF LINES def fnReadLines(strRead): try: flReader = open(strRead, "r") lstReader = flReader.readlines() flReader.close() except: # print "Oops! Could not read %s" % strRead lstReader = [strReadError] return lstReader def fnCleanReadLines(strRead): try: flReader = open(strRead, "r") lstReader = flReader.readlines() flReader.close() lstCleanReader = [] for strRead in lstReader: lstCleanReader.append(string.rstrip(strRead, "\n")) except: # print "Oops! Could not read %s" % strRead lstReader = [strReadError] return lstCleanReader # SPLITS YYYYMMDD-ThisIsTheNameOfTheAlbum to MM DD, YYYY - This Is The Name Of The Album FOR ALBUM OR STORY NAMES def fnSplitFileName(strFolderName): strSplitName = "" strSplit1 = "Year" strSplit2 = "0" strSplit3 = "Year" strSplit4 = "" strSplit5 = "" lstSplit1 = string.split(strFolderName,'-') if len(lstSplit1) == 1: lstSplit1.append(lstSplit1[0]) lstSplit1[0] = time.strftime("%Y%m%d") if len(lstSplit1[0]) > 3: strSplit1 = lstSplit1[0][0:4] if len(lstSplit1[0]) > 5: strSplit2 = lstSplit1[0][4:6] if len(lstSplit1[0]) > 7: strSplit3 = lstSplit1[0][6:8] intCtr1 = 0 for strSpliter1 in lstSplit1: if intCtr1 > 0: strSplit4 = strSplit4 + strSpliter1 intCtr1 = intCtr1 + 1 intCtr2 = 0 for chrChar in strSplit4: if ((chrChar.isupper())): if ((intCtr2 > 0) and ((strSplit4[intCtr2 - 1].isupper()))): strSplit5 = strSplit5 + " " + chrChar else: strSplit5 = strSplit5 + " " + chrChar elif ((chrChar.isdigit())): if ((intCtr2 > 0) and ((strSplit4[intCtr2 - 1].isdigit()))): strSplit5 = strSplit5 + chrChar else: strSplit5 = strSplit5 + " " + chrChar else: strSplit5 = strSplit5 + chrChar intCtr2 = intCtr2 + 1 strSplitName = calendar.month_name[int(strSplit2)] + " " + strSplit3+ ", " + strSplit1 + " - " + strSplit5 return strSplitName def fnConvertDate(strDate): strDate = strDate + "-Hello" strConvert = fnSplitFileName(strDate) strThisDate = string.split(strConvert, "-")[0] return strThisDate # PRIMARILY USED FOR DEBUGGING def fnPause(): strInput = raw_input("Hit enter key to continue") return 1 # READS THE CONFIG FILE FOR THE PROGRAM def fnReadConfig(): global strReport1Path, strReport3Path, strAlbumPath, strWebsitePath, binStory, binTouchMode, binEmbedVideo, intLogLevel, intThumbWidth, intThumbHeight, intThumbsWidthwise, strEmailIcon, binYouTube global binYTPrivate, strYTDeveloperKey, strYTClientId, strYTEmail, strYTPwd, strYTSource # Load the list of lines from the text file lstConfig = fnReadLines(strConfigFile) # Create individual lists of Narratives, dialogue, etc for strConfigLine in lstConfig: # For each line, check if it is one of the types of narratives intPrefixNumber = 0 for strConfigType in lstConfigTypes: # If it matches intPrefixNumber = intPrefixNumber + 1 if strConfigLine[0:len(strConfigType)] == strConfigType: # Strip the line off its preceding prefix and the succeeding newline character strConfigInLine = strConfigLine[len(strConfigType):].strip() # Numbers are from this list declared above - lstConfigTypes = ["strReport1Path", "strReport3Path", "strAlbumPath", "strWebsitePath", "binStory", "binTouchMode", "binEmbedVideo", "intLogLevel", "binYouTube", "binYTPrivate", "strYTDeveloperKey", "strYTClientId", "strYTEmail", "strYTPwd", "strYTSource"] # Append to the appropriate list if intPrefixNumber == 1: strReport1Path = strConfigInLine.strip() elif intPrefixNumber == 2: strReport3Path = strConfigInLine.strip() elif intPrefixNumber == 3: strAlbumPath = strConfigInLine.strip() elif intPrefixNumber == 4: strWebsitePath = strConfigInLine.strip() elif intPrefixNumber == 5: binStory = string.atoi(strConfigInLine.strip()) elif intPrefixNumber == 6: binTouchMode = string.atoi(strConfigInLine.strip()) elif intPrefixNumber == 7: binEmbedVideo = string.atoi(strConfigInLine.strip()) elif intPrefixNumber == 8: intLogLevel = string.atoi(strConfigInLine.strip()) elif intPrefixNumber == 9: binYouTube = string.atoi(strConfigInLine.strip()) elif intPrefixNumber == 10: binYTPrivate = string.atoi(strConfigInLine.strip()) elif intPrefixNumber == 11: strYTDeveloperKey = strConfigInLine.strip() elif intPrefixNumber == 12: strYTClientId = strConfigInLine.strip() elif intPrefixNumber == 13: strYTEmail = strConfigInLine.strip() elif intPrefixNumber == 14: strYTPwd = strConfigInLine.strip() elif intPrefixNumber == 15: strYTSource = strConfigInLine.strip() else: # Ignore any other kinds of lines ... we wouldn't know what to do with them pass if binStory: # Thumbnails will be the actual pictures in the story, so bigger intThumbWidth = 400 # The thumbnails in a story Album Page are the actual plates of the pictorial story ... we want them larger intThumbHeight = 300 intThumbsWidthwise = 3 # Fewer thumbnails across the Album Page since they are larger strEmailIcon = "../../Icons/email018.gif" # The location of the email image is different for the story albums, it has less depth than photo albums ... we need to fix all this if intLogLevel > 0: print """ Loaded Config: -------------- strReport1Path: [%s], strReport3Path: [%s], strAlbumPath: [%s], strWebsitePath: [%s], binStory: [%s], binTouchMode: [%s], binEmbedVideo: [%s], intLogLevel: [%s], binYouTube: [%s], binYTPrivate: [%s], strYTDeveloperKey: [%s], strYTClientId: [%s], strYTEmail: [%s], strYTPwd: [%s], strYTSource: [%s] """ % (strReport1Path, strReport3Path, strAlbumPath, strWebsitePath, binStory, binTouchMode, binEmbedVideo, intLogLevel, binYouTube, binYTPrivate, strYTDeveloperKey, strYTClientId, strYTEmail, strYTPwd, strYTSource) return 0 # PRINTS LOGS AT VARIOUS LEVELS OF SEVERITY def fnLog(intSeverity, strMessage): intNowLogLevel = intLogLevel if intSeverity < len(lstErrorLevels): strSeverity = lstErrorLevels[intSeverity] else: strSeverity = "Level: %02d" % intSeverity if intSeverity <= intNowLogLevel: print ">>>> LOG at SEVERITY LEVEL [%s] = [%s]" % (strSeverity, strMessage) # SPLITS NNN-ThisIsTheNameOfThePageFolder to [NNN, This Is The Name Of The Album] def fnFolderTitle(strFolderName): strSplitName = "" strSplit1 = "Year" strSplit2 = "0" strSplit3 = "Year" strSplit4 = "" strSplit5 = "" lstSplit1 = string.split(strFolderName,'-') if len(lstSplit1) == 1: lstSplit1.append(lstSplit1[0]) lstSplit1[0] = time.strftime("%Y%m%d") if len(lstSplit1[0]) > 3: strSplit1 = lstSplit1[0][0:4] if len(lstSplit1[0]) > 5: strSplit2 = lstSplit1[0][4:6] if len(lstSplit1[0]) > 7: strSplit3 = lstSplit1[0][6:8] intCtr1 = 0 for strSpliter1 in lstSplit1: if intCtr1 > 0: strSplit4 = strSplit4 + strSpliter1 intCtr1 = intCtr1 + 1 intCtr2 = 0 for chrChar in strSplit4: if ((chrChar.isupper())): # FOR RUNNING CAPS if ((intCtr2 > 0) and ((strSplit4[intCtr2 - 1].isupper()))): strSplit5 = strSplit5 + " " + chrChar # IF THE FIRST CHAR IS A CAP elif (intCtr2 == 0): strSplit5 = strSplit5 + "" + chrChar # FOR ALL OTHER CAPS, CHANGE THE WORD else: strSplit5 = strSplit5 + " " + chrChar # IF A DIGIT elif ((chrChar.isdigit())): # IF RUNNING DIGITS if ((intCtr2 > 0) and ((strSplit4[intCtr2 - 1].isdigit()))): strSplit5 = strSplit5 + chrChar # IF NOT RUNNING DIGITS, CHANGE THE WORD else: strSplit5 = strSplit5 + " " + chrChar else: strSplit5 = strSplit5 + chrChar intCtr2 = intCtr2 + 1 strSplitName = calendar.month_name[int(strSplit2)] + " " + strSplit3+ ", " + strSplit1 + " - " + strSplit5 return lstSplit1[0], strSplit5 # RUNS A PASS THROUGH THE SITE STRUCTURE BUILDING THE SITE MAP INCLUDING A LINKED LIST THAT WILL BE USED FOR BREADCRUMBS AND HIERARCHICAL MENUS def fnAnalyzeFolder(strFolderPath, strFolderName, intPageSerial): try: # LOCATE ALL FILES AND FOLDERS IN THIS FOLDER lstFolderContents = os.listdir(strRootPath + "/" + strFolderPath + "/" + strFolderName) fnLog(5, "Content of Folder: [%s/%s]: %s" % (strFolderPath, strFolderName, lstFolderContents)) fnLog(6, "Resolution of Path: PC [%s] and Web Server [/%s]" % (strRootPath + "/" + strFolderPath + "/" + strFolderName, strFolderPath + "/" + strFolderName)) # THE HOME PAGE IS ALREADY ANALYZED. FOR OTHERS ... if intPageSerial > 0: # FIND OUT IMPORTANT DETAILS TO LOAD INTO THE SITE MAP # Page Title try: if binFolderNameIsTitle: # TITLE IS CONSTRUCTED FROM THE FOLDER NAME ... strThisPageTitle = fnFolderTitle(strFolderName)[1] else: if lstMetaFiles[4] in lstFolderContents: fnLog(6, "Title: %s" % fnReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + lstMetaFiles[4])) # TITLE IS EXPLICITLY RECORDED IN THE TITLE FILE strThisPageTitle = fnReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + lstMetaFiles[4])[0] else: strThisPageTitle = strDefaultMetaTitle except: strThisPageTitle = strDefaultMetaTitle fnLog(6, strThisPageTitle) # Page SubTitle if lstMetaFiles[5] in lstFolderContents: fnLog(6, "SubTitle: %s" % fnReadLines(strRootPath + "/" + strFolderPath + "\\" + strFolderName + "\\" + lstMetaFiles[5])) strThisPageSubTitle = fnReadLines(strRootPath + "/" + strFolderPath + "\\" + strFolderName + "\\" + lstMetaFiles[5])[0] else: strThisPageSubTitle = strDefaultMetaSubTitle # Page Author if lstMetaFiles[3] in lstFolderContents: fnLog(6, "Author: %s" % fnReadLines(strRootPath + "/" + strFolderPath + "\\" + strFolderName + "\\" + lstMetaFiles[3])) strThisPageAuthor = fnReadLines(strRootPath + "/" + strFolderPath + "\\" + strFolderName + "\\" + lstMetaFiles[3])[0] else: strThisPageAuthor = strDefaultMetaAuthor # UPDATE THE SITE MAP arrLstSiteMap.append([intPageSerial, strThisPageTitle, strThisPageSubTitle, strThisPageAuthor, strFolderName, strFolderPath, lstParentPageSerialStack[len(lstParentPageSerialStack)-1], len(lstParentPageSerialStack)]) fnLog(5, "Sita Map Array = %s" % arrLstSiteMap) # NOTE DOWN PAGE SERIAL NUMBER IN ITS FOLDER try: os.remove(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + lstMetaFiles[12]) except: print "Couldn't erase" pass fnFileWrite(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + lstMetaFiles[12], "%d\n" % intPageSerial, "a") if binFolderNameIsTitle: try: fnFileWrite(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + lstMetaFiles[4], "%s" % fnFolderTitle(strFolderName), "w") except: pass # LOOK FOR SUB FOLDERS NOW # PUSH THE PARENT FOLDER SERIAL INTO STACK lstParentPageSerialStack.append(intPageSerial) fnLog(6, "Parent Stack = %s" % lstParentPageSerialStack) if strMetaAutoContentFileName in lstFolderContents: # THIS IS AN AUTOGENERATED FOLDER - DO NOT RECURSE FURTHER - STOP RIGHT HERE pass else: for strFolderContent in lstFolderContents: try: os.listdir(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strFolderContent) # IF NOT PROTECTED FOLDER, RECURSE if strFolderContent in lstProtectedFolders: pass else: # INCREMENT THE PAGE SERIAL COUNTER intPageSerial = intPageSerial + 1 # IF IT GETS HERE IT IS A FOLDER fnLog(2, "Processing Folder #%d: [%s | %s | %s]" % (intPageSerial, strFolderPath, strFolderName, strFolderContent)) # RECURSE TO PROCESS CHILDREN intPageSerial = fnAnalyzeFolder(strFolderPath + "/" + strFolderName, strFolderContent, intPageSerial) except: # NOT A FOLDER - DON'T BOTHER pass # POP THE FOLDER SERIAL FROM THE STACK lstParentPageSerialStack.pop() except: fnLog(1, "Pass 1 Folder Analysis failed on [%s] because of [%s]" % (strFolderName, sys.exc_info()[0])) return intPageSerial # FINDS BANNER IMAGES IN SPECIFIED FOLDER AND CONSTRUCTS A CLIENT SIDE JAVASCRIPT STRING WITH THE NAMES # THE PAGES SELECT A BANNER BASED ON TIME AND LOAD THEM DYNAMICALLY # THE FIRST IMAGE WILL BE THE DEFAULT THAT WILL STAY ON THE PAGE IF THE CLIENT SIDE JS LOAD FAILS - SO IT SHOULD BE A GOOD ONE # CLIENT SIDE JS LOAD LOGIC HAS BEEN TESTED TO WORK ON IE AND BLACKBERRY BROWSERS! def fnListBannersFound(strFolderPath): lstFiles = os.listdir(strFolderPath) lstBannerFiles = [] strBannerFiles = "" for strFileName in lstFiles: lstNamePieces = string.split(strFileName, ".") if lstNamePieces[1] == "jpg": if len(lstBannerFiles) == 0: strBannerFiles = "\"" + strFileName + "\"" else: strBannerFiles = strBannerFiles + ", \"" + strFileName + "\"" lstBannerFiles.append(lstNamePieces[0]) fnLog(6, "Banners found = [%s]" % strBannerFiles) return lstBannerFiles, strBannerFiles # GIVEN THE PAGE SERIAL NUMBER, THIS WILL FIND TITLE, SUBTITLE, AUTHOR, PARENT SERIAL, PAGE DEPTH INFO LOADED INTO THE SITE MAP IN ANALYSIS (FIRST) PASS def fnFindEntryInSiteMap(intPageSerial): for lstPageDetails in arrLstSiteMap: if int(lstPageDetails[0]) == int(intPageSerial): fnLog(5, lstPageDetails) return lstPageDetails fnLog(2, "Serial number [%s] not found." % intPageSerial) return [] # CONSTRUCTS AN HTML STRING CONTAINING THE BREADCRUMBS FOR THE GIVEN PAGE def fnBreadCrumbs(strBreadCrumbs, intPageSerial, intOriginalFolderDepth, binNavButtons): lstPageEntry = fnFindEntryInSiteMap(intPageSerial) intPageParent = int(lstPageEntry[6]) intPageDepth = int(lstPageEntry[7]) strFolder = lstPageEntry[4] strPath = lstPageEntry[5] strComments = lstPageEntry[2] strName = lstPageEntry[1] strNavigator = "" strPathToHomeFolder = "" for intDepthCtr in range(0, intOriginalFolderDepth-1): strPathToHomeFolder = strPathToHomeFolder + "../" if strBreadCrumbs == "": strNavigator = fnNavigator(intPageSerial) if binNavButtons: strBreadCrumbs = "%s%s" % (strPathToHomeFolder, strPath + "/" + strFolder, strPageFileName, strComments, strName, strNavigator) else: strBreadCrumbs = "%s" % (strPathToHomeFolder, strPath + "/" + strFolder, strPageFileName, strComments, strName) else: strBreadCrumbs = "%s > %s" % (strPathToHomeFolder, strPath + "/" + strFolder, strPageFileName, strComments, strName, strBreadCrumbs) if intPageSerial > 0: strBreadCrumbs = fnBreadCrumbs(strBreadCrumbs, intPageParent, intOriginalFolderDepth, binNavButtons) else: if binNavButtons: strBreadCrumbs = " """ lstMenuHtmls.append(strThisLevelHtml) # RECURSE FOR PARENT if intParentPageSerial > 0: fnBuildMenus(intParentPageSerial, lstMenuHtmls, intOriginalFolderDepth) fnLog(6, "List of Menu Links =: [%s]" % lstMenuHtmls) return lstMenuHtmls def fnBuildChildMenu(intPageSerial): # FIRST PASS: FIND ALL PAGES WITH THIS ONE AS PARENT ... IE ... CHILDREN # FIND PARENT lstSiblingSerials = [] lstMenuForThisPage = fnFindEntryInSiteMap(intPageSerial) # FIND DEPTH OF THE PAGE intThisPageDepth = lstMenuForThisPage[7] # intParentPageSerial = fnFindEntryInSiteMap(intPageSerial)[6] # FIND SIBLINGS AND LOAD INTO LIST # FOR EVERY PAGE IN THE SITE for lstPageDetails in arrLstSiteMap: # IF THE PAGE'S PARENT IS SAME AS THIS ONE intThisParentPageSerial = lstPageDetails[6] if intThisParentPageSerial == intPageSerial: # IT IS A CHILD lstSiblingSerials.append(lstPageDetails[0]) # ORDER THE LIST PER THE NUMERAL PREFIX # MAX PREFIX = 99 lstSiblingOrderedSerials = [] for intPrefix in range(0, 100): for intThisPageSerial in lstSiblingSerials: strThisPageName = fnFindEntryInSiteMap(intThisPageSerial)[4] intThisPagePrefix = int(fnFolderTitle(strThisPageName)[0]) # print ">>>>>>>>>>> %s|%s|%s" % (strThisPageName, intPrefix, intThisPagePrefix) if intThisPagePrefix == intPrefix: lstSiblingOrderedSerials.append(intThisPageSerial) # BUILD HTML strSampleMenuHtml = """ """ strThisLevelHtml = """ """ fnLog(6, "List of Child Menu Links =: [%s]" % strThisLevelHtml) return strThisLevelHtml # EMBEDS IMAGE HTML def fnAddImage(strPageContent, lstPageImage, intImagesAfterPara, intImageCounter, strFolderPath): intCaptionWidth = 300 intTableWidth = intImageWidth + intCaptionWidth for intImageCounter in range(intImageCounter, intImageCounter + intImagesAfterPara): if intImageCounter >= len(lstPageImage): intImageCounter = intImageCounter + 1 return strPageContent, intImageCounter strImageTxt = lstPageImage[intImageCounter] lstImageTxt = string.split(strImageTxt, "|") strImageLoc = lstImageTxt[0] if strImageLoc[0:4] == "http": strImageLink = strImageLoc elif strImageLoc[0:1] == "/": strImageLink = strSiteLink + strImageLoc else: strImageLink = strSiteLink + "/" + strFolderPath + "/" + strImageLoc if len(lstImageTxt) > 1: strImageCaption = lstImageTxt[1] else: strImageCaption = "Sandhir Image" strImageLink = string.replace(strImageLink, "/.//", "/") strImageHtml = """
" + strBreadCrumbs return strBreadCrumbs # FIND PARENT AND ADJACENT SIBLINGS OF PAGE FOR NAVIGATION BUTTONS - ASSUMES SITE-MAP-ARRAY IS SORTED FOR ADJACENCY OF SIBLINGS def fnNavigator(intPageSerial): strNavigator = "%03d" % intPageSerial lstPageEntry = fnFindEntryInSiteMap(intPageSerial) intPageDepth = int(lstPageEntry[7]) strFolder = lstPageEntry[4] strPath = lstPageEntry[5] strComments = lstPageEntry[2] strName = lstPageEntry[1] intOriginalFolderDepth = intPageDepth strNavigator = "" strPathToHomeFolder = "" for intDepthCtr in range(0, intOriginalFolderDepth-1): strPathToHomeFolder = strPathToHomeFolder + "../" # FIND OUT ABOUT THE PAGE lstPageEntry = fnFindEntryInSiteMap(intPageSerial) # FIND OUT ABOUT THE PARENT intPageParent = int(lstPageEntry[6]) if intPageParent < 0: # THIS IS THE HOME PAGE - NO PARENT strParentNav = " Page up: %s " % (strPathToHomeFolder, "X", "X") else: lstParentEntry = fnFindEntryInSiteMap(intPageParent) strParentFolder = lstParentEntry[4] strParentPath = lstParentEntry[5] strParentComments = lstParentEntry[2] strParentName = lstParentEntry[1] strParentNav = " Page up: %s " % (strPathToHomeFolder, strParentPath + "/" + strParentFolder, strPageFileName, strParentName, strPathToHomeFolder, strParentName, strParentName) # FIND OUT ABOUT ANY PRECEDING SIBLING intPrecedingSiblingSerial = -1 if intPageSerial > 2: # THERE IS NO WAY #1 COULD HAVE A PRECEDING SIBLING, AS IT IS THE FIRST PAGE UNDER #0, THE HOME PAGE for intMaybePS in range(intPageSerial-1, 0, -1): lstPrecedingSiblingEntry = fnFindEntryInSiteMap(intMaybePS) intPrecedingSiblingParent = int(lstPrecedingSiblingEntry[6]) strPrecedingSiblingFolder = lstPrecedingSiblingEntry[4] strPrecedingSiblingPath = lstPrecedingSiblingEntry[5] strPrecedingSiblingComments = lstPrecedingSiblingEntry[2] strPrecedingSiblingName = lstPrecedingSiblingEntry[1] if intPrecedingSiblingParent == intPageParent: # THEY HAVE A COMMON PARENT - THEY SEEM TO BE TRUE SIBLINGS! intPrecedingSiblingSerial = intMaybePS break if intPrecedingSiblingSerial > 0: strPrecedingSiblingNav = "Prev page: %s" % (strPathToHomeFolder, strPrecedingSiblingPath + "/" + strPrecedingSiblingFolder, strPageFileName, strPrecedingSiblingName, strPathToHomeFolder, strPrecedingSiblingName, strPrecedingSiblingName) else: strPrecedingSiblingNav = " Prev page: %s " % (strPathToHomeFolder, "X", "X") # FIND OUT ABOUT ANY SUCCEEDING SIBLING intSucceedingSiblingSerial = -1 if intPageSerial < intNumberOfPages: # THERE IS NO WAY #1 COULD HAVE A PRECEDING SIBLING, AS IT IS THE FIRST PAGE UNDER #0, THE HOME PAGE for intMaybeSS in range(intPageSerial+1, intNumberOfPages+1, 1): lstSucceedingSiblingEntry = fnFindEntryInSiteMap(intMaybeSS) intSucceedingSiblingParent = int(lstSucceedingSiblingEntry[6]) strSucceedingSiblingFolder = lstSucceedingSiblingEntry[4] strSucceedingSiblingPath = lstSucceedingSiblingEntry[5] strSucceedingSiblingComments = lstSucceedingSiblingEntry[2] strSucceedingSiblingName = lstSucceedingSiblingEntry[1] if intSucceedingSiblingParent == intPageParent: # THEY HAVE A COMMON PARENT - THEY SEEM TO BE TRUE SIBLINGS! intSucceedingSiblingSerial = intMaybeSS break if intSucceedingSiblingSerial > 0: strSucceedingSiblingNav = "Next page: %s" % (strPathToHomeFolder, strSucceedingSiblingPath + "/" + strSucceedingSiblingFolder, strPageFileName, strSucceedingSiblingName, strPathToHomeFolder, strSucceedingSiblingName, strSucceedingSiblingName) else: strSucceedingSiblingNav = " Next page: %s " % (strPathToHomeFolder, "X", "X") strNavigator = strPrecedingSiblingNav + strParentNav + strSucceedingSiblingNav return strNavigator # BUILD A SECTION WITH LIST OF CHILD PAGES def fnBuildChildSection(intPageSerial): # Site Map = Page Serial, Page Title, Page SubTitle, Page Author, Page Folder Name, Page Folder Path, Parent Page Serial, Depth lstChildSection = ["","Pages","
    "] lstChildrenPages = [] for intPageNumber in range(intNumberOfPages+1): lstThisPage = fnFindEntryInSiteMap(intPageNumber) if lstThisPage[6] == intPageSerial: lstChildrenPages.append(lstThisPage[0]) lstChildrenPages.sort() for intChildPageSerial in lstChildrenPages: lstThisPage = fnFindEntryInSiteMap(intChildPageSerial) lstChildSection.append("
  • %s: %s
  • " % (lstThisPage[4], strPageFileName, lstThisPage[1], lstThisPage[2])) lstChildSection.append("
") if len(lstChildrenPages): return lstChildSection else: return [] # FIND ALL THE PARENTS OF THE PAGE - THEY ARE ALL META TAGS def fnFindAllParents(intPageNumber, lstParentNumbers, lstParentNames): # LOAD THE FILE NAME ITSELF lstParentNumbers.append(intPageNumber) lstParentNames.append(fnFindEntryInSiteMap(intPageNumber)[1]) # FIND THE IMMEDIATE PARENT TO RECURSE intParentPageSerial = fnFindEntryInSiteMap(intPageNumber)[6] # KEEP FINDING PARENTS OF PARENT UNTIL HOME PAGE IS REACHED if intParentPageSerial > 0: lstParentNumbers, lstParentNames = fnFindAllParents(intParentPageSerial, lstParentNumbers, lstParentNames) return lstParentNumbers, lstParentNames def fnBuildMenus(intPageSerial, lstMenuHtmls, intOriginalFolderDepth): # FIRST PASS: FIND ALL PAGES AT SAME LEVEL AS PAGE ... IE ... ALL PAGES WITH SAME PARENT ... IE ... SIBLINGS # FIND PARENT lstSiblingSerials = [] lstMenuForThisPage = fnFindEntryInSiteMap(intPageSerial) intParentPageSerial = lstMenuForThisPage[6] # OVERRIDE WITH ORIGINAL FOLDER DEPTH # intParentPageSerial = intOriginalFolderDepth # FIND DEPTH OF THE PAGE intThisPageDepth = intOriginalFolderDepth # FIND SIBLINGS AND LOAD INTO LIST # FOR EVERY PAGE IN THE SITE for lstPageDetails in arrLstSiteMap: # IF THE PAGE'S PARENT IS SAME AS THE ONE intThisParentPageSerial = lstPageDetails[6] if intThisParentPageSerial == intParentPageSerial: # IT IS A SIBLING lstSiblingSerials.append(lstPageDetails[0]) # ORDER THE LIST PER THE NUMERAL PREFIX # MAX PREFIX = 99 lstSiblingOrderedSerials = [] for intPrefix in range(0, 100): for intThisPageSerial in lstSiblingSerials: strThisPageName = fnFindEntryInSiteMap(intThisPageSerial)[4] intThisPagePrefix = int(fnFolderTitle(strThisPageName)[0]) # print ">>>>>>>>>>> %s|%s|%s" % (strThisPageName, intPrefix, intThisPagePrefix) if intThisPagePrefix == intPrefix: lstSiblingOrderedSerials.append(intThisPageSerial) # BUILD HTML - HIGHLIGHT THIS PAGE THOUGH intLevelCtr = len(lstMenuHtmls)+1 strThisLevelHtml = """
""" # SHADE OF MENU DEPENDS ON DEPTH - TOP MOST IS BRIGHTEST if intLevelCtr > 7: intLevelCtr = 7 strMenuShade = lstMenuBgdColors[intLevelCtr] intCtr1 = 0 for intSiblingPageSerial in lstSiblingOrderedSerials: intCtr1 = intCtr1 + 1 lstPageDetails = fnFindEntryInSiteMap(intSiblingPageSerial) # DEPTH OF THE PAGE THAT IS BEING PUT ON MENU DOES NOT MATTER # intThisFolderDepth = lstPageDetails[7] strPathToHomeFolder = "" for intDepthCtr in range(0, intThisPageDepth-1): strPathToHomeFolder = strPathToHomeFolder + "../" strThisPageName = lstPageDetails[1] strThisPageUrl = strPathToHomeFolder + lstPageDetails[5] + "/" + lstPageDetails[4] + "/" + strPageFileName fnLog(5, "Menu from Page [" + lstMenuForThisPage[1] + "] TO Page [" + strThisPageName + "], the RELATIVE URL is [" + strThisPageUrl + "]") strThisPageAlt = lstPageDetails[2] # FOR THIS PAGE, if intSiblingPageSerial == intPageSerial: # DEACTIVATE LINK FOR THIS SPECIFIC PAGE (YOU ARE ALREADY ON IT!) if len(lstMenuHtmls) == 0: # strThisLevelHtml = strThisLevelHtml + "| This Page: %s " % (strThisPageUrl, strThisPageAlt, strThisPageName) strThisLevelHtml = strThisLevelHtml + """ """ % (intLevelCtr, intCtr1, strThisPageName) # ELSE IF A DIRECT PARENT, THEN SHOW LINK, BUT HIGHLIGHT AS A PARENT else: # strThisLevelHtml = strThisLevelHtml + "| This Page: %s " % (strThisPageUrl, strThisPageAlt, strThisPageName) strThisLevelHtml = strThisLevelHtml + """ """ % (intLevelCtr, intCtr1, strThisPageUrl, strThisPageAlt, strThisPageName) # FOR SIBLING PAGES else: # strThisLevelHtml = strThisLevelHtml + "| %s " % (strThisPageUrl, strThisPageAlt, strThisPageName) strThisLevelHtml = strThisLevelHtml + """ """ % (intLevelCtr, intCtr1, strMenuShade, strThisPageUrl, strThisPageAlt, strThisPageName) if intCtr1 == 0: strThisLevelHtml = strThisLevelHtml + "" strThisLevelHtml = strThisLevelHtml + """ """ intCtr1 = 0 for intSiblingPageSerial in lstSiblingOrderedSerials: intCtr1 = intCtr1 + 1 lstPageDetails = fnFindEntryInSiteMap(intSiblingPageSerial) strThisPageName = lstPageDetails[1] strThisPageUrl = "/" + lstPageDetails[5] + "/" + lstPageDetails[4] + "/" + strPageFileName strThisPageAlt = lstPageDetails[2] # FOR THIS PAGE, if intSiblingPageSerial == intPageSerial: # DEACTIVATE LINK FOR THIS SPECIFIC PAGE (YOU ARE ALREADY ON IT!) if len(lstMenuHtmls) == 0: strThisLevelHtml = strThisLevelHtml + """ """ % (intLevelCtr, intCtr1, "#aa4400") # ELSE IF A DIRECT PARENT, THEN SHOW LINK, BUT HIGHLIGHT AS A PARENT else: strThisLevelHtml = strThisLevelHtml + """ """ % (intLevelCtr, intCtr1, "#eeeeee") # FOR SIBLING PAGES else: strThisLevelHtml = strThisLevelHtml + """ """ % (intLevelCtr, intCtr1, "#eeeeee") if intCtr1 == 0: strThisLevelHtml = strThisLevelHtml + "" strThisLevelHtml = strThisLevelHtml + """
""" intCtr1 = 0 for intSiblingPageSerial in lstSiblingOrderedSerials: intCtr1 = intCtr1 + 1 lstPageDetails = fnFindEntryInSiteMap(intSiblingPageSerial) strThisPageName = lstPageDetails[1] strThisPageUrl = "/" + lstPageDetails[5] + "/" + lstPageDetails[4] + "/" + strPageFileName strThisPageAlt = lstPageDetails[2] # strThisLevelHtml = strThisLevelHtml + "| %s " % (strThisPageUrl, strThisPageAlt, strThisPageName) strThisLevelHtml = strThisLevelHtml + """ """ % intCtr1 if intCtr1 == 0: strThisLevelHtml = strThisLevelHtml + "" strThisLevelHtml = strThisLevelHtml + """ """ intCtr1 = 0 for intSiblingPageSerial in lstSiblingOrderedSerials: intCtr1 = intCtr1 + 1 lstPageDetails = fnFindEntryInSiteMap(intSiblingPageSerial) # DEPTH OF THE PAGE THAT IS BEING PUT ON MENU DOES NOT MATTER # intThisFolderDepth = lstPageDetails[7] strPathToHomeFolder = "" for intDepthCtr in range(0, intThisPageDepth-1): strPathToHomeFolder = strPathToHomeFolder + "../" strThisPageName = lstPageDetails[1] strThisPageUrl = strPathToHomeFolder + lstPageDetails[5] + "/" + lstPageDetails[4] + "/" + strPageFileName strThisPageAlt = lstPageDetails[2] # strThisLevelHtml = strThisLevelHtml + "| %s " % (strThisPageUrl, strThisPageAlt, strThisPageName) strThisLevelHtml = strThisLevelHtml + """ """ % (intCtr1, strThisPageUrl, strThisPageAlt, strThisPageName) if intCtr1 == 0: strThisLevelHtml = strThisLevelHtml + "" strThisLevelHtml = strThisLevelHtml + """
%s
%s

""" % (intTableWidth, intTableWidth - 250, intTableWidth - 275, strImageBackground, strImageLink, intImageWidth, strImageCaption, strImageLink, strImageCaption) strPageContent = strPageContent + strImageHtml intImageCounter = intImageCounter + 1 return strPageContent, intImageCounter # CREATES ALL THE WEB PAGES def fnPublishFolder(intTotalPages): for intPageNumber in range(0,intTotalPages+1): # Site Map = Page Serial, Page Title, Page SubTitle, Page Author, Page Folder Name, Page Folder Path, Parent Page Serial, Depth lstPageEntry = fnFindEntryInSiteMap(intPageNumber) strFolderPath = lstPageEntry[5] strFolderName = lstPageEntry[4] intPageSerial = intPageNumber try: pass except: pass if 1: # LOCATE FOLDER SERIAL NUMBER lstFolderContents = os.listdir(strRootPath + "/" + strFolderPath + "/" + strFolderName) # IF SERIAL NUMBER FOUND, THEN if strMetaSerialFileName in lstFolderContents: # LOAD THE SERIAL NUMBER AND RELATED INFO FROM ANALYSIS PASS intPageSerial = int(fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaSerialFileName)[0]) lstThisFolder = fnFindEntryInSiteMap(intPageSerial) intThisFolderDepth = lstThisFolder[7] strPathToHomeFolder = "" for intDepthCtr in range(0, intThisFolderDepth-1): strPathToHomeFolder = strPathToHomeFolder + "../" fnLog(5, "Folder Serial = [%d] Map = [%s]" % (intPageSerial, lstThisFolder)) # DETERMINE BREADCRUMBS FOR THIS PAGE strHtmlBreadCrumbs = fnBreadCrumbs("", intPageSerial, intThisFolderDepth, 1) fnLog(5, strHtmlBreadCrumbs) # LOAD META DATA # AUTHOR INFO (MULTIPLE SUPPORTED) if strMetaAuthorFileName in lstFolderContents: lstAuthorText = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaAuthorFileName) else: lstAuthorText = [strDefaultMetaAuthor] strAuthorHtml = "" for strAuthorText in lstAuthorText: if len(strAuthorHtml) == 0: strAuthorHtml = strAuthorText else: strAuthorHtml = strAuthorHtml + ", " + strAuthorText # TITLE AND SUB-TITLE WERE LOADED IN FIRST PASS strTitleText = lstPageEntry[1] strSubTitleText = lstPageEntry[2] # IF VERSION INFO EXISTS, LOAD THE LIST, BUT USE ONLY THE TOP VALUE # IF IT DOESN'T, ASSUME IT IS VERSION 1.0 AND INIT THE TIME TO THE LAST MODIFY TIME OF THE CONTENT FILE # AND IF THAT FAILS, IT IS SIMPLY VERSION 1.0 WITH NO TIME ASSIGNMENT # DATE SHOULD BE PROVIDED IN YYYYMMDD FORMAT if strMetaVersionFileName in lstFolderContents: lstVersionText = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaVersionFileName) strVersionText = lstVersionText[0] lstVersionDetails = string.split(strVersionText, "|") # IF VERSION INFO INCLUDES TIME, CONVERT IT if len(lstVersionDetails) > 1: strVersionDate = lstVersionDetails[1] strVersionDate = fnConvertDate(strVersionDate) lstVersionText = [lstVersionDetails[0] + " of " + strVersionDate] # ELSE USE THE VERSION INFO AND CALC TIME FROM CONTENT FILE UPDATE DATE else: if strMetaContentFileName in lstFolderContents: lstVersionText = ["%s of %s" % (lstVersionDetails[0], time.asctime(time.localtime(os.stat(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaContentFileName).st_mtime)))] elif strMetaSpecialContentFileName in lstFolderContents: lstVersionText = ["%s of %s" % (lstVersionDetails[0], time.asctime(time.localtime(os.stat(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaSpecialContentFileName).st_mtime)))] else: pass else: # ELSE DEFAULT THE VERSION INFO AND CALC THE TIME try: # lstVersionText = ["Version 1.0"] lstVersionText = ["%s of %s" % (strDefaultMetaVersion, time.asctime(time.localtime(os.stat(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaContentFileName).st_mtime)))] fnLog(6, "Calculated version of [%s] = [%s]" % (strFolderName, lstVersionText)) # AND IF ALL ELSE FAILS, JUST MENTION V INFO except: lstVersionText = [strDefaultMetaVersion] strVersionHtml = "" for strVersionText in lstVersionText: if len(strVersionHtml) == 0: strVersionHtml = strVersionText else: strVersionHtml = strVersionHtml + ", " + strVersionText # LOAD META TAGS if strMetaTagsFileName in lstFolderContents: lstMetaTagText = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaTagsFileName) else: lstMetaTagText = lstDefaultMetaTags # LOAD TYPES OF MEDIA FILES SUPPORTED if strMetaMediaFileTypesFileName in lstFolderContents: lstMediaFileTypes = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaMediaFileTypesFileName) else: lstMediaFileTypes = strDefaultMetaMediaFileTypes # LOAD LIST OF LINKS - REFERENCES (ABSOLUTE) AND ATTACHMENTS (LOCAL OR ABSOLUTE) if strMetaReferenceLocalLinksFileName in lstFolderContents: lstLocalLinks = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaReferenceLocalLinksFileName) else: lstLocalLinks = strDefaultMetaReferenceLocalLinks if strMetaReferenceWebLinksFileName in lstFolderContents: lstWebLinks = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaReferenceWebLinksFileName) else: lstWebLinks = strDefaultMetaReferenceWebLinks # LOAD PREFERRED FONTS FOR THIS PAGE if strMetaFontStyleFileName in lstFolderContents: lstFontTypes = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaFontStyleFileName) else: lstFontTypes = lstDefaultMetaFontStyle strFontHtml = "" for strFontText in lstFontTypes: if len(strFontHtml) == 0: strFontHtml = strFontText else: strFontHtml = strFontHtml + ", " + strFontText # LOAD PREFERRED BACKGROUND FOR THIS PAGE strBKGD = strDefaultBKGD if strMetaBKGDFileName in lstFolderContents: strBKGD = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaBKGDFileName)[0] if strBKGD == "": strBKGD = strDefaultBKGD if strBKGD[0] == "#": strBKGDFile = "" strBKGDColor = strBKGD else: strBKGDFile = strBKGD strBKGDColor = "" strBKGD = strPanelBackground # BUILD META ELEMENTS FOR FACEBOOK strMetaTitle = "" % strTitleText strMetaDescription = "" % strSubTitleText lstMedia = lstLocalLinks for strWebLink in lstWebLinks: lstMedia.append(strWebLink) binFoundAnImage = 0 for strMedia in lstMedia: lstLinkName = string.split(strMedia, "|") if len(lstLinkName) > 1: lstLinkExt = string.split(lstLinkName[0], ".") if len(lstLinkExt) > 1: if string.lower(lstLinkExt[1]) in strDefaultMetaMediaFileTypes: binFoundAnImage = 1 strMetaImageLink = lstLinkName[0] strMetaImageDesc = lstLinkName[1] if strMetaImageLink[0:4] == "http": strMetaImageLink = strMetaImageLink elif strMetaImageLink[0:1] == "/": strMetaImageLink = strSiteLink + strMetaImageLink else: strMetaImageLink = strSiteLink + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaImageLink break if binFoundAnImage == 0: strMetaImageLink = "%s/%s/%s" % (strSiteLink, strLogoFolder, strDefaultLogoFile) strMetaImageDesc = "Sandhir" strMetaImageLink = string.replace(strMetaImageLink, "/.//", "/") strMetaImage = "" % (strMetaImageLink) # BUiLD META ELEMENTS FOR GOOGLE SPIDERS strMetaTags = "" # ADD ALL PARENT PAGE NAMES AS META TAGS !!!! HOW COOL IS THAT? lstPageParentSerials, lstAdditionalMetaTags = fnFindAllParents(intPageNumber, [], []) for strMetaTag in lstMetaTagText: if len(strMetaTags) == 0: strMetaTags = strMetaTag else: strMetaTags = strMetaTags + ", " + strMetaTag for strMetaTag in lstAdditionalMetaTags: strMetaTags = strMetaTags + ", " + strMetaTag strMetaTags = "" % strMetaTags fnLog(5, "Meta Data = [%s|%s|%s|%s]" % (strMetaTitle, strMetaDescription, strMetaImage, strMetaTags)) # BUILD OTHER META ELEMENTS strPageGlobalUrl = strSiteLink + "/" + strFolderPath + "/" + strFolderName + "/" + strPageFileName strPageGlobalUrl = string.replace(strPageGlobalUrl, "/.//", "/") strPageGlobalDes = "%s - %s" % (strTitleText, strSubTitleText) # ===== LOADING OF THE LIST OF BANNER IMAGES IS DONE GLOBALLY ===== # BUILD HTML FOR ALL THE LINKS strLinksHtml = "
    " lstPageImage = [] for strWebLink in lstMedia: # IF IT IS A LOCAL LINK PUT AN ATTACHMENT ICON binAttach = 1 if strWebLink[0:4] == "http": binAttach = 0 if binAttach: strThisIcon = strAttachIcon strType = "" else: # ELSE, PUT A WEB ICON strThisIcon = strWebLinkIcon strType = "" strTarget = "" if binOpensNewPage: strTarget = " target='_blank' " strLink = string.split(strWebLink, "|") strLinksHtml = strLinksHtml + "
  • Reference %s
  • " % (strPathToHomeFolder + strThisIcon, strLink[0], strTarget, strLink[1]) # IF THE LINK IS FOR AN IMAGE, LOAD INTO IMAGE LIST lstLinkExt = string.split(strLink[0], ".") if len(lstLinkExt) > 1: if string.lower(lstLinkExt[1]) in strDefaultMetaMediaFileTypes: lstPageImage.append(strWebLink) strLinksHtml = strLinksHtml + "
" # BUILD ALL THE TOP LINKS - FONT-SIZE, PRINT, FACEBOOK, TWITTER, EMAIL, SITE MAP # PERFORMED BELOW # FIND PEER AND PARENT MENUS lstMenuHtmls = fnBuildMenus(intPageNumber, [], intThisFolderDepth) lstMenuHtmls.reverse() strMenus = "" for strMenuHtml in lstMenuHtmls: strMenus = strMenus + strMenuHtml + "" # FIND CHILD MENUS strChildMenuHtml = fnBuildChildMenu(intPageNumber) # BUILD FOOTER - VERSION, COPYRIGHT, PRIVACY, SUPPORT (HTML, CSS, LINUX, PYTHON), META TAGS # LOAD THE CONTENT if strMetaContentFileName in lstFolderContents: lstContentText = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaContentFileName) else: lstContentText = [strDefaultMetaContent] if strMetaSpecialContentFileName in lstFolderContents: lstSpecialContentText = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaSpecialContentFileName) else: lstSpecialContentText = [strDefaultMetaSpecialContent] # If Auto generated content exists (such as album pages, etc), special content is replaced with it if strMetaAutoContentFileName in lstFolderContents: lstSpecialContentText = fnCleanReadLines(strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strMetaAutoContentFileName) # ADD A SECTION AT THE BOTTOM FOR CHILD PAGES lstChildSection = fnBuildChildSection(intPageSerial) if len(lstChildSection): for strChildSectionLine in lstChildSection: lstContentText.append(strChildSectionLine) # SPECIAL CONTENT IS APPENDED TO NORMAL CONTENT - NO SPECIAL HANDLING AS YET # for strSpecialContentText in lstSpecialContentText: # lstContentText.append(strSpecialContentText) # BUILD ALL THE IMAGES # USE THE IMAGE LIST BUILT OUT OF ATTACHMENT/WEBLINK LIST # WE EVENLY SPACE THEM BETWEEN CONTENT PARAS intNumberOfContentParas = len(lstContentText) + len(lstSpecialContentText) intNumberOfPageImages = len(lstPageImage) if intNumberOfContentParas > intNumberOfPageImages: if intNumberOfPageImages == 0: intParasAfterImage = 1 else: intParasAfterImage = int(float(intNumberOfContentParas) / float(intNumberOfPageImages)) intImagesAfterPara = 1 else: intParasAfterImage = 1 if intNumberOfContentParas == 0: intImagesAfterPara = 1 else: intImagesAfterPara = int(float(intNumberOfPageImages) / float(intNumberOfContentParas)) if intImagesAfterPara > intMaxNumberImagesPerRow: intImagesAfterPara = intMaxNumberImagesPerRow # BUILD THE CONTENT BODY strPageContent = "" intParaCounter = 0 intImageCounter = 0 # MARKUP THE CONTENT WITH APPROPRIATE HTML # , , AS

,

,

# LEFT AS THEY ARE ... STYLES WILL APPLY GLOBALLY # TITLE SECTION strHeadingStructureStart = """
""" % strPageBackground strHeadingStructureEnd = """ Top of the Page
""" % strPathToHomeFolder # INLINE FRAME SECTION strInlineIframeStart = "
" # EMBEDDED YOUTUBE VIDEO SECTION strYTEmbed1Start = """
" strYTEmbed2Start = "
""" % (intImageWidth*2, intImageWidth*2*9/16) # PAGE SECTION lstPageSections = [[]] if len(lstContentText) > 0: if len(lstContentText[0]) >= 0: intCtr = -1 for strContentTxt in lstContentText: strHeaderTxt = "" intCtr = intCtr + 1 if strContentTxt.startswith(("","","")): fnLog(4, "HEADER: [%s]" % strContentTxt) strContentTxt = string.replace(strContentTxt, "", "1:") strContentTxt = string.replace(strContentTxt, "", "") strContentTxt = string.replace(strContentTxt, "", "2:") strContentTxt = string.replace(strContentTxt, "", "") strContentTxt = string.replace(strContentTxt, "", "3:") strContentTxt = string.replace(strContentTxt, "", "") if len(strContentTxt) > 0: # THIS LINE HAD A HEADER # LIST CONTAINS: Section Heading, Section Level (H2 = 1; H3 = 2; H3 = 3), Despaced Section Heading (to be used as anchors), Line number of the header so that we can insert anchors below lstPageSections.append([strContentTxt[2:], int(strContentTxt[0], 10), string.replace(string.replace(strContentTxt[2:], " ", ""), "'", ""), intCtr]) # BUILD SECTION HEADER CONTENTS strSectionListing = "" intCurrentLevel = 0 intCtr = 0 if len(lstPageSections) > 0: strSectionListing = strSectionListing + "
    \n" for lstPageSection in lstPageSections: if len(lstPageSection) == 4: intCtr = intCtr + 1 strLead = "" if lstPageSection[1] == 1: strLead = "> " elif lstPageSection[1] == 2: strLead = "> > " elif lstPageSection[1] == 3: strLead = "> > > " strSectionListing = strSectionListing + "
  • %s%s
  • \n" % (strLead, lstPageSection[2], lstPageSection[0], (4 - lstPageSection[1]), lstPageSection[0]) intCurrentLevel = lstPageSection[1] strSectionListing = strSectionListing + "
\n" # REPLACEMENTS if len(lstContentText) > 0: if len(lstContentText[0]) >= 0: intCtr = -1 for strContentTxt in lstContentText: intCtr = intCtr + 1 strAnchor = "" for lstPageSection in lstPageSections: if len(lstPageSection) == 4: if lstPageSection[3] == intCtr: strAnchor = "
" % lstPageSection[2] strContentTxt = string.replace(strContentTxt, "", strHeadingStructureStart + "\n%s

" % strAnchor) strContentTxt = string.replace(strContentTxt, "", "

\n" + strHeadingStructureEnd) strContentTxt = string.replace(strContentTxt, "", strHeadingStructureStart + "\n%s

" % strAnchor) strContentTxt = string.replace(strContentTxt, "", "

\n" + strHeadingStructureEnd) strContentTxt = string.replace(strContentTxt, "", strHeadingStructureStart + "\n%s

" % strAnchor) strContentTxt = string.replace(strContentTxt, "", "

\n" + strHeadingStructureEnd) strContentTxt = string.replace(strContentTxt, "", strInlineIframeStart) strContentTxt = string.replace(strContentTxt, "", strInlineIframeEnd) strContentTxt = string.replace(strContentTxt, "", strYTEmbed1Start) strContentTxt = string.replace(strContentTxt, "", strYTEmbed1End) strContentTxt = string.replace(strContentTxt, "", strYTEmbed2Start) strContentTxt = string.replace(strContentTxt, "", strYTEmbed2End) lstContentText[intCtr] = strContentTxt # CONTENT LINES ARE PLACED IN PARAS, INTERSPERSED WITH IMAGES if len(lstContentText) > 0: if len(lstContentText[0]) >= 0: for strContentTxt in lstContentText: intParaCounter = intParaCounter + 1 if (math.fmod(intParaCounter, intParasAfterImage)): strPageContent, intImageCounter = fnAddImage(strPageContent, lstPageImage, intImagesAfterPara, intImageCounter, strFolderPath + "/" + strFolderName) # strPageContent = strPageContent + "

" + strContentTxt + "

" # IF LINES END WITH TAGS '>' THEN DO NOT PUT
if (len(strContentTxt)>0): if (strContentTxt[len(strContentTxt)-1] == '>'): strPageContent = strPageContent + "\n" + strContentTxt # ELSE ADD A CR / LINE CHANGE /
else: strPageContent = strPageContent + "\n" + strContentTxt + "
" else: strPageContent = strPageContent + "\n" + strContentTxt + "
" # SPECIAL CONTENT LINES ARE PLACED AS IS, INTERSPERSED WITH IMAGES if len(lstSpecialContentText) > 0: if len(lstSpecialContentText[0]) >= 0: # strPageContent = strPageContent + "

\n" strPageContent = strPageContent + "\n" for strContentTxt in lstSpecialContentText: intParaCounter = intParaCounter + 1 if (math.fmod(intParaCounter, intParasAfterImage)): strPageContent, intImageCounter = fnAddImage(strPageContent, lstPageImage, intImagesAfterPara, intImageCounter, strFolderPath + "/" + strFolderName) strPageContent = strPageContent + "" + strContentTxt + "" # strPageContent = strPageContent + "

\n" strPageContent = strPageContent + "
\n" # FOR THE REMAINING IMAGES, THEY ARE ADDED ONE BY ONE BELOW if intImageCounter >= intNumberOfPageImages: for intImageCounter in range(intImageCounter, intNumberOfPageImages-intImageCounter): strPageContent, intIgnoredImageCounter = fnAddImage(strPageContent, lstPageImage, 1, intImageCounter, strFolderPath + "/" + strFolderName) strPageContent = strPageContent + "
" # BUILD PAGE HTML ==================== strPageHtml = "" # HEAD strTemp = """ """ strPageHtml = strPageHtml + """ Sandhïr2 %s %s %s %s %s """ % (strTitleText, strPathToHomeFolder, strPathToHomeFolder, strMetaTitle, strMetaDescription, strMetaImage, strMetaTags, strBKGDFile, strPageBackground, "", strFontHtml, strFontHtml, strFontHtml, strPageBackground, strSidePanelBackgroundLeft, strSidePanelBackgroundRight, strSidePanelBackgroundTopLeft, strSidePanelBackgroundTopTop, strSidePanelBackgroundTopRight, strSidePanelBackgroundBottomLeft, strSidePanelBackgroundBottomBottom, strSidePanelBackgroundBottomRight, strImageBackgroundGrafx, strHeaderBackgroundGrafx, strTopBanners, strPathToHomeFolder, strPathToHomeFolder) # BODY strPageHtml = strPageHtml + """ %s %s
Banner
Google Search HotKey 's' RSS Feed Post on Facebook Post on Twitter Print This Page Email Site Map vCard File [Change Font SizeReduce Size/Increase Size] [Scroll DownPause ScrollScroll Faster/Scroll Slower]

%s

%s

%s, %s
%s

%s

References and Other Links

%s

Sections on This Page

%s
(c) 1999-2011 Sandipan Gangopadhyay | www.Sandipan.com | Sandhir Content Publisher | Valid HTML 4.01 Transitional | Valid CSS! | [Valid RSS] | Python Powered | Linux Counter #278581 | Meta Tags |
""" % (strPathToHomeFolder, strPathToHomeFolder, strRSSFolder, strRSSFile, strPathToHomeFolder, strPathToHomeFolder, urllib.quote(strPageGlobalDes), strPathToHomeFolder, strPathToHomeFolder, strPathToHomeFolder, strSiteMapFolder, strPageFileName, strPathToHomeFolder, strPathToHomeFolder, strPathToHomeFolder, strPathToHomeFolder, strPathToHomeFolder, strPathToHomeFolder, strPathToHomeFolder, strPathToHomeFolder, strPathToHomeFolder, strMenus, strChildMenuHtml, intSideBarWidth, intSideBarWidth, intSideBarWidth, strPanelBackground, strBKGDColor, strFontHtml, strTitleText, strFontHtml, strSubTitleText, strAuthorHtml, strVersionHtml, strHtmlBreadCrumbs, strPanelBackground, strPageContent, strFontHtml, strLinksHtml, strFontHtml, strSectionListing, intSideBarWidth, intSideBarWidth, intSideBarWidth, strMetaTagsFileName, strPageGlobalUrl) # NAVIGATION STUFF if len(strChildMenuHtml) >0: strChildMenuHtml = strChildMenuHtml + "

" # TAIL strPageHtml = strPageHtml + """ """ strPagePathName = strRootPath + "/" + strFolderPath + "/" + strFolderName + "/" + strPageFileName try: # WRITE PAGE HTML fnFileWrite(strPagePathName, strPageHtml, "w") # RECORD THE PAGE DATA FOR RSS FEED lstRSSFeed.append(lstThisFolder) # LOG IT fnLog(2, "Processed page folder: [%s]" % strPagePathName) except: fnLog(1, "Failed to write to page file for folder %s" % strPagePathName) pass else: fnLog(1, "Serial count not found in folder: [%s\\%s]; aborting." % (strFolderPath, strFolderName)) return try: pass except: fnLog(1, "Pass 2 Folder Publish failed on [%s] because of [%s]" % (strFolderName, sys.exc_info()[0])) return # TRIGGERS THE (FIRST) ANALYSIS PASS TO BUILD THE SITE MAP def fnFirstPass(strStartPath, strStartFolder): fnLog(2, ">>> FIRST PASS: ANALYZING PAGE FOLDER STRUCTURE STARTING AT PAGE-FOLDER [%s] AT PATH [%s] >>>" % (strStartFolder, strStartPath)) intNumberOfPages = fnAnalyzeFolder(strStartPath, strStartFolder, intPageSerial) fnLog(2, "Pages found = %s" % intNumberOfPages) return intNumberOfPages # TRIGGERS THE (SECOND) PUBLISH PASS TO BUILD THE PAGES def fnSecondPass(intNumberOfPages): fnLog(2, ">>> SECOND PASS: PUBLISHING %d PAGES >>>" % intNumberOfPages) intPageSerial = 0 fnPublishFolder(intNumberOfPages) return # BUILD THE SITE MAP PAGE def fnBuildSiteMap(intNumberOfPages): strSiteMap = "
    " # FOR EACH ENTRY IN SITE MAP ARRAY intCurrentDepth = 1 for lstPageDetails in arrLstSiteMap: # Site Map = Page Serial, Page Title, Page SubTitle, Page Author, Page Folder Name, Page Folder Path, Parent Page Serial, Depth strRSSTitle = lstPageDetails[1] strRSSDescription = lstPageDetails[2] strRSSAuthor = lstPageDetails[3] strRSSSequence = fnFolderTitle(lstPageDetails[4])[0] strRSSLink = strSiteLink + "/" + lstPageDetails[5] + "/" + lstPageDetails[4] + "/" + strPageFileName strRSSLink = string.replace(strRSSLink, "/.//", "/") # Depth should be of Site Map page, not the page we are generating bread crumbs for! ... strRSSHtmlBreadCrumbs = fnBreadCrumbs("", lstPageDetails[0], lstPageDetails[7]) strRSSHtmlBreadCrumbs = fnBreadCrumbs("", lstPageDetails[0], 2, 0) # SIMPLE ENTRY: strRSSSiteEntry = "Page ID [%s]: Title: %s - %s [%s] - (Description: %s by Author: %s)" % (lstPageDetails[0], strRSSLink, strRSSSequence, strRSSTitle, strRSSHtmlBreadCrumbs, strRSSDescription, strRSSAuthor) strRSSSiteEntry = """Page ID [%s]: Title: %s - %s
    • Hierarchy: [%s]
    • Description: %s
    • Author: %s

    """ % (lstPageDetails[0], strRSSLink, strRSSSequence, strRSSTitle, strRSSHtmlBreadCrumbs, strRSSDescription, strRSSAuthor) # IF GOING DEEPER THEN INDENT if intCurrentDepth > lstPageDetails[7]: intIndent = intCurrentDepth - lstPageDetails[7] strIndenter = "" for intIndenter in range(0, intIndent): strIndenter = strIndenter + "
" strSiteMap = strSiteMap + strIndenter + "
  • " + strRSSSiteEntry + "
  • \n" intCurrentDepth = lstPageDetails[7] # IF COMING OUT, THEN DETENT elif intCurrentDepth < lstPageDetails[7]: intIndent = lstPageDetails[7] - intCurrentDepth strIndenter = "" for intIndenter in range(0, intIndent): strIndenter = strIndenter + "
      " strSiteMap = strSiteMap + strIndenter + "
    1. " + strRSSSiteEntry + "
    2. \n" intCurrentDepth = lstPageDetails[7] # ELSE JUST ADD ANOTHER LIST ITEM else: strSiteMap = strSiteMap + "
    3. " + strRSSSiteEntry + "
    4. \n" intCurrentDepth = lstPageDetails[7] strSiteMap = strSiteMap + "
    " # SAVE IT try: fnFileWrite(strRootPath + "/" + strSiteMapFolder + "/" + strMetaSpecialContentFileName, strSiteMap, "w") except: fnLog(1, "Error writing new Site Map file") pass return # BUILD AN RSS DOC THAT CONTAINS LINKS, TITLES, DESCRIPTION, AUTHOR, VERSION OF ALL PAGES THAT CHANGED IN THIS RUN # IT WILL BACK UP PAST FEED FIRST def fnBuildRSSFeed(intNumberOfPages): # FIND EXISTING RSS FEED FILES lstFiles = os.listdir(strRootPath + "/" + strRSSFolder) strExistingRSSDate = "" # IF ANY EXIST if strRSSFile in lstFiles: lstExistingRSSLines = [] try: # LOAD EM UP lstExistingRSSLines = fnCleanReadLines(strRootPath + "/" + strRSSFolder + "/" + strRSSFile) strExistingRSSXML = "" for strExistingRSSLines in lstExistingRSSLines: strExistingRSSXML = strExistingRSSXML + strExistingRSSLines + "\n" # FIND THEIR TIME STAMP strExistingRSSDate = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime(os.stat(strRootPath + "/" + strRSSFolder + "/" + strRSSFile).st_mtime)) objExistingRSSTimeStamp = time.localtime(os.stat(strRootPath + "/" + strRSSFolder + "/" + strRSSFile).st_mtime) strExistingRSSTimeStamp = "%s-%04d%02d%02d%02d%02d%02d.%s" % (string.split(strRSSFile, ".")[0], objExistingRSSTimeStamp[0], objExistingRSSTimeStamp[1], objExistingRSSTimeStamp[2], objExistingRSSTimeStamp[3], objExistingRSSTimeStamp[4], objExistingRSSTimeStamp[5], string.split(strRSSFile, ".")[1]) # SAVE THEM AS BACKUP fnFileWrite(strRootPath + "/" + strRSSFolder + "/" + strExistingRSSTimeStamp, strExistingRSSXML, "w") except: fnLog(1, "Error backing up existing RSS file") pass strItems = "" intItems = 0 strTimeStamp = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.localtime(time.time())) strTimeStamp2 = time.asctime(time.localtime(time.time())) # FOR EACH PAGE FOLDER PROCESSED for lstPageDetails in lstRSSFeed: intItems = intItems + 1 # Site Map = Page Serial, Page Title, Page SubTitle, Page Author, Page Folder Name, Page Folder Path, Parent Page Serial, Depth strRSSTitle = lstPageDetails[1] strRSSDescription = lstPageDetails[2] strRSSLink = strSiteLink + "/" + lstPageDetails[5] + "/" + lstPageDetails[4] + "/" + strPageFileName strRSSLink = string.replace(strRSSLink, "/.//", "/") fnLog(6, "RSS Added for Page Serial %d: TITLE:%s | DESC:%s | LINK:%s | PUB:%s" % (lstPageDetails[0], strRSSTitle, strRSSDescription, strRSSLink, strTimeStamp)) strGUID = "%d%d" % (math.floor(time.time()), intItems) strGUID = strRSSLink strItems = strItems + """ %s %s %s %s %s """ % (strRSSTitle, strRSSDescription, strRSSLink, strGUID, strTimeStamp) # BUILD THE RSS FEED strRSSFeed = """ %s Updates to Sandipan's Website %s %s %s %s """ % (strSiteLink + "/" + strRSSFolder + "/" + strRSSFile, "Sandipan's RSS Feed: %s" % strSiteLink, strSiteLink + "/" + strRSSFolder + "/" + strRSSFile, strExistingRSSDate, strTimeStamp, strItems) # SAVE IT try: fnFileWrite(strRootPath + "/" + strRSSFolder + "/" + strRSSFile, strRSSFeed, "w") except: fnLog(1, "Error writing new RSS file") pass return # Utilization / Requirements # ========================== # - Each folder represents one page # - Folder hierarchy represents page hierarchy # - Pages have: # - Top banner (either random which is not nice ... distracts users, or changes client-side every x minutes which is better) # - Image Map for link to Sandhir logo # - Next Row will have links to # - Social sites - FaceBook, Twitter, Email, Print, Link to Site Map, Link to Home # - Next Rows will have Menu # - All levels above with parent highlighted # - Peer levels with itself highlighted # - One level of Children # - Menu structures # - Highlight colors will become darker from parent to child # - Title will be displayed with SubTitle as ALT for Mouse-over # - All static - will work everywhere # - Content # - Title # - SubTitle # - Author (Photo, Name, Contact); Version, Date # - Bread crumbs # - Content # - Content can be HTML within BODY tag with the following tags allowed ... ,

    ,

     at this point
    #       - Footer
    #           - Copyright Info
    #           - Code Version Info and Link
    #           - Generation Data (When, Number of Pages, 
    #   - Special Content Pages such as albums will be treated differently
    #   - Special Pages will be auto-generated such as
    #       - Site Map
    #       - Index (based on tags) 
    
    # Algorithm
    # =========
    
    # Init std file names
    # 	Content File
    # 	Author Name
    # 	Title Name
    # 	Version Info
    # 	Content Tags
    # 	Media Files
    # 		JPG, PNG
    # 		YT links
    # 		Links to Sandhir Albums with the thumbnail of the album showing up
    # 	References
    # 	Attachments
    # 	Array
    # 		Serial, Title, SubTitle, Author, Parent Serial
    # Pass 1
    # 	Recurse
    # 	Find Content
    # 	Register in Array
    #   If Special Content file exists, register the special page, and then, bail <<<<
    # 	Find un-protected sub-folders
    # 		go into each
    # 		Register in Array
    # 		Recurse
    # Load up Banner List <<<<
    # Load up Author List <<<<
    # Pass 2
    # 	List of files
    # 		If web file exists, bail
    #       If Special Content file exists, load up the special page, and then, bail
    # 		Locate content file
    # 		Title file
    # 		Sub Title File
    # 		Tags
    # 		Author File
    # 		Date File
    # 		Determine number of media files
    # 	List of sub-folders
    # 		Exclude protected folders
    # 		List of Folders
    # 		Go into them and find out Titles, SubTitles
    
    global strRootPath, lstErrorLevels, intNumberOfPages, arrLstSiteMap, intPageSerial, strPageFileName, lstTopBanners, strTopBanners, intNumberOfMenuLinksPerRow, lstRSSFeed, lstSiteMap # THESE COUNTERS, FLAGS, AND VARIABLES ARE ACCESSIBLE THROUGHOUT THE APP
    
    # ORGANIZATION AND INITIALIZATION OF PAGE CONTENT AND META DATA
    strMetaContentFileName = "MetaContent.txt"
    strDefaultMetaContent = ""
    strMetaSpecialContentFileName = "MetaSpecialContent.txt"
    strDefaultMetaSpecialContent = ""
    strMetaAutoContentFileName = "MetaAutoContent.txt"
    strDefaultMetaAutoContent = ""
    strMetaAuthorFileName = "MetaAuthor.txt"
    strDefaultMetaAuthor = "Sandipan Gangopadhyay"
    strMetaTitleFileName = "MetaTitle.txt"
    binFolderNameIsTitle = 1
    strDefaultMetaTitle = "Sandhir"
    strMetaSubTitleFileName = "MetaSubTitle.txt"
    strDefaultMetaSubTitle = "Sandhir Web P"
    strMetaVersionFileName = "MetaVersion.txt" 
    strDefaultMetaVersion = "Version 1.0"
    strMetaTagsFileName = "MetaTags.txt"
    lstDefaultMetaTags = ["Sandhir", "www.Sandipan.com", "www.Gangopadhyay.com", "www.Dhirja.com", "Family", "Personal"]
    strMetaBKGDFileName = "MetaBackground.txt"
    strDefaultBKGD = "#ffffff"
    strMetaMediaFileTypesFileName = "MetaMediaFileTypes.txt"
    strDefaultMetaMediaFileTypes = ["jpg", "png"]
    strMetaReferenceLocalLinksFileName = "MetaReferenceLocalLinks.txt"
    strDefaultMetaReferenceLocalLinks = ["http://www.Sandipan.com|Sandhir"]
    strMetaReferenceWebLinksFileName = "MetaReferenceWebLinks.txt"
    strDefaultMetaReferenceWebLinks = ["http://www.Sandipan.com|Sandhir"]
    strMetaFontStyleFileName = "MetaFontStyle.txt"
    lstDefaultMetaFontStyle = ["Arial"]
    
    lstErrorLevels = ["N/A", "CRITICAL! PROGRAM TERMINATED", "THIS YOU GOTTA SEE", "KEEP TABS ON WHAT IS GOING ON", "SEE WHAT'S HAPPENNING IN THERE", "FIGURE OUT HOW IT REALLY WORKS", "FIGURE OUT EVEN MORE HOW IT WORKS - THIS IS GONNA TAKE FOREVER"]
    
    strSiteLink = "http://www.Gangopadhyay.com" # WHICH SITE IS THIS FOR
    strRootPath = "new/Site" # PATH TO THE SITE
    # KEY FILE NAMES
    strMetaSerialFileName = "MetaSerial.txt"
    strPageFileName = "index.html"
    strSiteMapFolder = "09-SiteMap"
    lstSiteMap = []
    strRSSFolder = "RSSFeeds"
    lstRSSFeed = []
    strRSSFile = "SandhirRSS.xml"
    binOverwritePageHtmlFiles = 1 # FOR FASTER RUNS, THIS SWITCH CONTROLS WHETHER EXISTING PAGE HTML FILES WILL BE OVERWRITTEN OR ONLY NEW PAGES/FOLDERS WILL BE PROCESSED (THOSE WITHOUT THE PAGE HTML FILE)
    strDefaultLogoFile = "SandhirLogo.jpg" # LOGO USED AS PAGE META IMAGE, SAY FOR FACEBOOK, IF PAGE HAS NO IMAGE ASSOCIATED WITH IT
    strAttachmentIcon = "pastedpic_01102009_223621.png" # NOT USED
    strAttachIcon = "/Logos/PixeloPhilia/bag.png" # ICON USED TO SIGNIFY LINK OPENS UP A LOCAL LINK
    strWebLinkIcon = "/Logos/PixeloPhilia/link.png" # ICON USED TO SIGNIFY LINK OPENS UP A WEB LINK
    strImageBackground = "/Logos/Tile_n_001.png"
    strPanelBackground = "/Logos/Tile_n_013.png"
    strPageBackground = "/Logos/88829-wallpaper06.jpg"
    strPageBackground = "/Logos/wallpaper-texture-background-desktop.jpg"
    strSidePanelBackgroundLeft = "/Backgrounds/SidePanelLeft3.png"
    strSidePanelBackgroundRight = "/Backgrounds/SidePanelRight3.png"
    strSidePanelBackgroundLeft = "/Backgrounds/shadow-LL2.png"
    strSidePanelBackgroundRight = "/Backgrounds/shadow-RR2.png"
    strSidePanelBackgroundTopLeft = "/Backgrounds/shadow-TL2.png"
    strSidePanelBackgroundTopTop = "/Backgrounds/shadow-TT2.png"
    strSidePanelBackgroundTopRight = "/Backgrounds/shadow-TR2.png"
    strSidePanelBackgroundBottomLeft = "/Backgrounds/shadow-BL2.png"
    strSidePanelBackgroundBottomBottom = "/Backgrounds/shadow-BB2.png"
    strSidePanelBackgroundBottomRight = "/Backgrounds/shadow-BR2.png"
    strImageBackgroundGrafx = strImageBackground
    strHeaderBackgroundGrafx = "/Logos/texture_pattern_light_background_gradient_ultra_3840x2160_hd-wallpaper-238406.jpg"
    binOpensNewPage = 1 # THIS MAKES LINKS ON PAGES OPEN IN NEW WINDOWS
    intMaxNumberImagesPerRow = 2
    intImageWidth = 240
    intSideBarWidth = 50
    lstProtectedFolders = ["CommonImages", "Logos", "Backgrounds", "SiteMap", "style", strRSSFolder, "PageFolderTemplate", "PrivateFolder"] # THESE FOLDERS ARE NOT PROCESSED AS PAGES AND THEREFORE NOT RECURSED WITHIN
    lstMetaFiles = [strMetaContentFileName, strMetaSpecialContentFileName, strMetaAutoContentFileName, strMetaAuthorFileName, strMetaTitleFileName, strMetaSubTitleFileName, strMetaVersionFileName, strMetaTagsFileName, strMetaMediaFileTypesFileName, strMetaReferenceLocalLinksFileName, strMetaReferenceWebLinksFileName, strMetaFontStyleFileName, strMetaSerialFileName, strMetaBKGDFileName] # NAMES OF FILES THAT HOLD INFO ABOUT THE PAGE IN THE PAGE FOLDER
    intNumberOfMenuLinksPerRow = 10 # MAX NUMBER OF PAGES AT ANY LEVEL
    lstMenuBgdColors = ["#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff", "#ffffff"] # SHADING OF MENUS AS WE GO DEEPER AND DEEPER
    lstMenuBgdColors = ["#000088", "#0000ff", "#008800", "#00ff00", "#00ff88", "#00ffff", "#880000", "#ff0000"] # SHADING OF MENUS AS WE GO DEEPER AND DEEPER
    lstMenuBgdColors = ["#cccccc", "#d4d4d4", "#d8d8d8", "#dadada", "#dddddd", "#e4e4e4", "#eaeaea", "#eeeeee"] # SHADING OF MENUS AS WE GO DEEPER AND DEEPER
    arrLstSiteMap = [100] # INITIALIZING THE SITE MAP BUILT IN THE FIRST PASS
    # Site Map = Page Serial, Page Title, Page SubTitle, Page Author, Page Folder Name, Page Folder Path, Parent Page Serial, Depth
    arrLstSiteMap[0] = [0, "Sandipan.com", "Dhirja and Sandipan Gangopadhyay", "Sandipan Gangopadhyay", "", ".", -1, 1] # TOP FOLDER = "Site" # SEEDING THE FIRST PAGE - THE HOME PAGE
    intPageSerial = 0 # INIT THE PAGE COUNTER
    lstParentPageSerialStack = [0] # INIT THE PAGE COUNTER STACK REQUIRED FOR RECURSING
    intNumberOfPages = 0
    
    strBannerFolder = "new/Site/CommonImages/TopTitleImages"
    strWebBannerFolder = "/CommonImages/TopTitleImages"
    strLogoFolder = "/Logos"
    fnFileWrite(strMetaSerialFileName, "0", "w")
    
    print "Sandhir Content Publisher Version " + strCodeVersion
    print "===================================="
    os.chdir(".")
    fnReadConfig()
    print "Running at Log Level %d" % intLogLevel
    # os.chdir(strAlbumPath)
    try:
        os.remove(strPortalPage)
    except:
        pass
    # FIND OUT THE PROCESSED BANNERS
    lstTopBanners, strTopBanners = fnListBannersFound(strBannerFolder)
    # RUN A FIRST PASS TO DETERMINE SITE STRUCTURE
    intNumberOfPages = fnFirstPass(".", arrLstSiteMap[0][4])
    # BUILD A SITE MAP
    fnBuildSiteMap(intNumberOfPages)
    # BUILD AND WRITE ALL THE PAGES
    fnSecondPass(intNumberOfPages)
    # BUILD THE RSS FEED
    fnBuildRSSFeed(intNumberOfPages)
    # fnWrite(fnRead("PageTemplates/part-a.txt"))
    strTimeStamp = time.asctime(time.localtime(time.time()))
    # fnWrite("List generated on " + strTimeStamp)
    # fnWrite(fnRead("PageTemplates/part-b.txt"))
    # fnWrite(fnListFolder(".", strReport1Path))
    # fnWrite("
    ") # fnWrite(fnListFolder(".", strReport2Path)) # fnWrite("

    A total of %d item(s) in %d albums published as of %s.

    \n" % (intTotalItems, len(lstAlbums), strTimeStamp)) # fnWrite(fnRead("PageTemplates/part-c.txt")) try: os.remove(strTempFile) except: pass # for a in range(0,10000000): # pass print print "Done" print "Thanks for using Sandhir Content Publisher Version " + strCodeVersion print strInput = raw_input("Hit enter key to end program")