def network_setup(self): dict = {} self.net_mtime = self.network_connect() if self.net_mtime != None: if os.path.exists( self.user_data_file ): self.network_update() local_mtime = int(os.stat( self.user_data_file ).st_mtime) if local_mtime > self.net_mtime: self.network_upload() elif local_mtime < self.net_mtime: self.network_download() else: self.network_download() if os.path.exists( self.user_data_file ): ph = open( self.user_data_file ) dict = Unpickler( ph ).load()[-1] if not os.path.exists( self.user_data_file ) and self.net_mtime == None: ph = open( self.user_data_file, 'w+' ) Pickler( ph ).dump( dict ) ph.close() os.utime( self.user_data_file, (0,0) ) last_month = dateDelta( date.today() ).get_last_month() keys = dict.keys() keys.sort() for key in keys: if key[:7] < '%0.4d-%0.2d' % (last_month.year,last_month.month): dict.pop( key ) else: break self.freetime.update( dict )
class freetimeConfig(myConfigParser): def __init__(self): self.error = None self.groups_pos = 0 defaults_dir = os.path.join( sys.prefix, 'share', 'nugsl-freetime') path = homeDir( topdir='FreeTime' ) path = os.path.join( path, 'FreeTime') if not os.path.exists( path ): os.makedirs( path ) config_path = os.path.join( path, 'Config') if not os.path.exists( config_path ): os.makedirs( config_path ) data_path = os.path.join( path, 'Calendars') if not os.path.exists( data_path ): os.makedirs( data_path ) self.data_path = data_path self.category_path = {} p = os.path.join( data_path, 'Staff') if not os.path.exists( p ): os.makedirs( p ) self.category_path[ 'Staff' ] = p p = os.path.join( data_path, 'Student') if not os.path.exists( p ): os.makedirs( p ) self.category_path[ 'Student' ] = p config_file = os.path.join( config_path, 'profile.txt' ) if not os.path.exists( config_file ): default_file = os.path.join( defaults_dir, 'profile-default.txt') default = open( default_file ).read() open( config_file, 'w+' ).write( default ) self.error = 'Please edit your profile at %s.' % config_file return myConfigParser.__init__(self, {'language': 'en'}) self.paranoid_read( config_file ) if not 'User' in self.sections(): self.error = 'Missing section [User] in config file %s' % config_file return elif not self.has_option('User','name'): self.error = 'Missing option "name:" in section [User] of config file %s' % config_file return elif not self.has_option('User','email'): self.error = 'Missing option "email:" in section [User] of config file %s' % config_file return elif not self.has_option('User','telephone'): self.error = 'Missing option "telephone:" in section [User] of config file %s' % config_file return lang = self.get('User','language') self.name = self.get('User', 'name') if self.name == 'Unknown User': self.error = 'Please edit your profile at %s.' % config_file return self.email = self.get('User', 'email') self.telephone = self.get('User', 'telephone') repeat_icon_file = os.path.join( defaults_dir, 'repeat.png') img = Image.open( repeat_icon_file, 'r' ) self.repeat_icon = ImageTk.PhotoImage( img ) empty_icon_file = os.path.join( defaults_dir, 'empty.png') img = Image.open( empty_icon_file, 'r' ) self.empty_icon = ImageTk.PhotoImage( img ) right_file = os.path.join( defaults_dir, 'right.png') img = Image.open( right_file, 'r' ) self.right = ImageTk.PhotoImage( img ) left_file = os.path.join( defaults_dir, 'left.png') img = Image.open( left_file, 'r' ) self.left = ImageTk.PhotoImage( img ) self.times = freetimeTimes( defaults_dir, lang=lang ).times self.weekdays = freetimeWeekdays( defaults_dir, lang=lang ).weekdays self.month = monthConfig( self.weekdays ) userkey = userkeyConfig( defaults_dir, config_path ) self.error = userkey.error if self.error: self.error = 'Please add your Freetime key to use the calendar.' return self.userkey = userkey.get('UserKey', 'userkey') if self.userkey == 'UnknownUser': self.error = 'Please add your Freetime key to use the calendar.' return self.category = userkey.get('UserKey', 'category') pkey = StringIO() pkey.write( userkey.get('UserKey','rsa').lstrip() ) pkey.seek(0) self.pkey = RSAKey.from_private_key( pkey ) self.server = userkey.get('UserKey', 'server') self.server_account = userkey.get('UserKey','account') groups_file = os.path.join( config_path, 'groups.txt' ) if os.path.exists( groups_file ): text = open( groups_file ).read() try: text = text.decode('utf8') except: text = text.decode('shift_jis') print 'Barfed on groups file, using shift-jis encoding' self.groups = [x[1:-1] for x in re.findall('\[[^]]+\]'.decode('utf8'), text )] else: self.groups = [] if self.groups: self.groups.insert(0, 'Personal') ##print self.groups # # Reconcile old group data and current groups configuration self.groups_data_file = os.path.join( config_path, 'groups.pkl' ) if os.path.exists( self.groups_data_file ): ph = open( self.groups_data_file ) self.groups_data = Unpickler( ph ).load() ph.close() else: self.groups_data = {} for key in self.groups_data.keys(): if not key in self.groups: self.groups_data.pop(key) for group in self.groups: if not self.groups_data.has_key( group ): self.groups_data[ group ] = [] self.build_user_info() self.known_hosts_file = os.path.join( defaults_dir, 'known_hosts') self.user_data_file = os.path.join( data_path, self.category, self.userkey ) self.freetime = freeTime() def build_user_info(self): self.users = {'Staff': [], 'Student': []} today = date.today() self.user_index = {} for category in ['Staff','Student']: ids = os.listdir( self.category_path[ category ] ) for userid in ids: userfile = os.path.join( self.category_path[ category ], userid ) ph = open( userfile ) try: userdata = Unpickler( ph ).load() doit = True except EOFError: ph.close() os.unlink( userfile ) doit = False if doit: ph.close() fullname = userdata[1].strip() email = userdata[2].strip() telephone = userdata[3].strip() mtime = os.stat( userfile ).st_mtime filedate = date.fromtimestamp( mtime ) delta = today - filedate age = delta.days self.users[ category ].append( (userid, fullname, email, telephone, age) ) self.users[ category ].sort( self.sort_ids ) for pos in range(0, len(self.users[ category ]),1): # # Ugly but effective. We'll need a wrapper function to keep the # usage of this unified key straight. self.user_index[ category + '::' + self.users[ category][pos][0] ] = pos def sort_ids(self, a, b): a = a[0].split('_')[-1] b = b[0].split('_')[-1] if a > b: return 1 elif a == b: return 0 else: return -1 def network_setup(self): dict = {} self.net_mtime = self.network_connect() if self.net_mtime != None: if os.path.exists( self.user_data_file ): self.network_update() local_mtime = int(os.stat( self.user_data_file ).st_mtime) if local_mtime > self.net_mtime: self.network_upload() elif local_mtime < self.net_mtime: self.network_download() else: self.network_download() if os.path.exists( self.user_data_file ): ph = open( self.user_data_file ) dict = Unpickler( ph ).load()[-1] if not os.path.exists( self.user_data_file ) and self.net_mtime == None: ph = open( self.user_data_file, 'w+' ) Pickler( ph ).dump( dict ) ph.close() os.utime( self.user_data_file, (0,0) ) last_month = dateDelta( date.today() ).get_last_month() keys = dict.keys() keys.sort() for key in keys: if key[:7] < '%0.4d-%0.2d' % (last_month.year,last_month.month): dict.pop( key ) else: break self.freetime.update( dict ) def groups_save(self): ph = open(self.groups_data_file, 'w+' ) Pickler( ph ).dump( self.groups_data ) ph.close() def network_connect(self): self.sshclient = SSHClient() self.sshclient.set_missing_host_key_policy(AutoAddPolicy) self.sshclient.load_host_keys( self.known_hosts_file ) try: self.sshclient.connect( self.server, username=self.server_account, pkey=self.pkey, timeout=20 ) except: # Should have logging for this. self.sshclient.close() self.sshclient = None return None self.sftp = self.sshclient.open_sftp() if self.userkey in self.sftp.listdir( self.category ): return self.sftp.stat( self.category + '/' + self.userkey ).st_mtime else: return 0 def network_close(self): if self.sshclient: self.sftp.close() self.sshclient.close() else: # # Setting the mtime to zero will force a merge, rather # than an overwrite, when the Net is next accessed. os.utime( self.user_data_file, (0,0)) def network_upload(self): #if self.sshclient and self.userkey in self.sftp.listdir( self.category ): if self.sshclient and self.userkey in os.listdir( os.path.join( self.data_path, self.category ) ): self.sftp.put( self.user_data_file, self.category + '/' + self.userkey ) mtime = self.sftp.stat( self.category + '/' + self.userkey ).st_mtime os.utime( self.user_data_file, (mtime,mtime) ) def network_download(self): if self.sshclient and self.userkey in self.sftp.listdir( self.category ): self.sftp.get( self.category + '/' + self.userkey, self.user_data_file ) mtime = self.sftp.stat( self.category + '/' + self.userkey ).st_mtime os.utime( self.user_data_file, (mtime,mtime) ) # # The mtime of the local file is held at zero until # the first network connection from this instance. # If the local mtime is zero when network is available, # update from the server rather than overwriting, to # avoid losing data. def network_update(self): # # We have network, we have local file, we may not have # remote file. if self.userkey in self.sftp.listdir( self.category ): local_mtime = os.stat( self.user_data_file ).st_mtime if int(local_mtime) == 0: self.sftp.get( self.category + '/' + self.userkey, self.user_data_file + '.tmp' ) ph = open( self.user_data_file + '.tmp' ) net_data = Unpickler( ph ).load()[-1] ph.close() os.unlink( self.user_data_file + '.tmp' ) ph = open( self.user_data_file ) local_data = Unpickler( ph ).load()[-1] ph.close() local_data.update( net_data ) self.freetime = freeTime( dict=local_data ) ph = open( self.user_data_file, 'w+' ) Pickler( ph ).dump( self.bundle_data() ) ph.close() else: self.sftp.put( self.user_data_file, self.category + '/' + self.userkey ) mtime = self.sftp.stat( self.category + '/' + self.userkey ).st_mtime os.utime( self.user_data_file, (mtime,mtime) ) def network_update_others(self, category): """ Download files of other users for use in coordinating group schedules """ for file in self.sftp.listdir( category ): if category == self.category and file == self.userkey: continue self.sftp.get( category + '/' + file, os.path.join( self.data_path, category, file ) ) mtime = self.sftp.stat( category + '/' + file ).st_mtime os.utime( os.path.join( self.data_path, category, file ), (mtime,mtime) ) self.build_user_info() def bundle_data(self): bundle = [] bundle.append( self.userkey ) bundle.append( self.name ) bundle.append( self.email ) bundle.append( self.telephone ) bundle.append( self.freetime.copy() ) return bundle