def PrepareWriteDir(self, arg, mode='normal', post_entry=None): if not arg.map_dir(): return False if arg.needlock: Util.FLock(arg.fd) if post_entry: (newpost, newid) = self.FindPost(arg.ent, post_entry.id, mode) if newpost is None: Util.FUnlock(arg.fd) return False arg.ent = newid return True
def Lock(): #try: #SemLock.Lock(Config.UCACHE_SEMLOCK, timeout = 10); #return 0; #except BusyError: #return -1; # Log.debug("Utmp.Lock enter()") lockf = os.open(Config.BBS_ROOT + "UTMP", os.O_RDWR | os.O_CREAT, 0600) if (lockf < 0): Log.error("Fail to open lock file!") raise Exception("fail to lock!") Util.FLock(lockf, shared = False) # Log.debug("Utmp.Lock succ()") return lockf
def index_board(self, board): """ Index one board (name: board)""" boardobj = BoardManager.BoardManager.GetBoard(board) if not boardobj: Log.error("Error loading board %s" % board) return if board in self.board_info: idx_obj = self.board_info[board] else: idx_obj = IndexBoardInfo(board, 0) self.board_info[board] = idx_obj bdir_path = boardobj.GetDirPath() with open(bdir_path, 'rb') as bdir: Util.FLock(bdir, shared=True) try: if not board in self.state.locks: self.state.locks[board] = threading.Lock() status = os.stat(bdir_path) if status.st_mtime <= idx_obj.last_idx: # why <? anyway... return Log.debug("Board %s updated. Indexing..." % board) # index into buffer table self.init_buf(board) for idx in xrange(status.st_size / PostEntry.PostEntry.size): post_entry = PostEntry.PostEntry( bdir.read(PostEntry.PostEntry.size)) self.insert_entry(board, post_entry, idx) self.conn.commit() # commit buffer table self.state.locks[board].acquire() try: self.remove_idx_status(idx_obj) self.commit_buf(board) self.create_db_index(board) idx_obj.last_idx = status.st_mtime self.insert_idx_status(idx_obj) finally: self.state.locks[board].release() Log.debug("Board %s indexed." % board) finally: Util.FUnlock(bdir)
def EditPost(self, session, post_xid, post_id=0, new_title=None, content=None, mode='normal', attach_to_remove=set(), add_attach_list=[]): (post_entry, post_id) = self.FindPost(post_id, post_xid, mode) if post_entry is None: raise NotFound("post not found") if (self.name == "syssecurity" or self.name == "junk" or self.name == "deleted"): raise WrongArgs("can't edit post in board %s" % self.name) if mode == "junk" or mode == "deleted": raise WrongArgs("can't edit post in mode %s" % mode) if self.CheckReadonly(): raise WrongArgs("board %s is read-only" % self.name) user = session.GetUser() if not post_entry.CanBeEdit(user, self): raise NoPerm("you can't edit this post") if self.DeniedUser(user): raise NoPerm("you can't edit on board %s" % self.name) post_path = self.GetBoardPath(post_entry.filename) post = Post(post_path, post_entry) if content is None: content = post.GetBody() first_attach_pos = 0 need_update = False new_post_path = post_path + ".new" if new_title is not None and new_title != Util.gbkDec( post_entry.title): post_entry.title = Util.gbkEnc(new_title) need_update = True with open(post_path, "r+b") as postf: Util.FLock(postf) try: attach_list = post.GetAttachList() newpost = Post(new_post_path, post_entry) newpost.open() try: newpost.EditHeaderFrom(post, new_title) size_header = newpost.pos() newpost.EditContent(content, session, post) content_len = newpost.pos() - size_header if content_len != post_entry.eff_size: post_entry.eff_size = content_len need_update = True # copy original attachments orig_attach_id = 0 for attach_entry in attach_list: if not orig_attach_id in attach_to_remove: try: attach_pos = newpost.AppendAttachFrom( post, attach_entry) if first_attach_pos == 0: first_attach_pos = attach_pos except: pass orig_attach_id += 1 # add new attachments for attach_entry in add_attach_list: filename = attach_entry['name'] tmpfile = attach_entry['store_id'] if (not store.Store.verify_id(tmpfile)): continue tmpfile = store.Store.path_from_id(tmpfile) try: attach_pos = newpost.AddAttachSelf( filename, tmpfile) if first_attach_pos == 0: first_attach_pos = attach_pos except Exception as e: Log.warn("fail to add attach: %r" % e) finally: newpost.close() os.rename(new_post_path, post_path) finally: try: os.remove(new_post_path) except: pass Util.FUnlock(postf) if first_attach_pos != post_entry.attachment: post_entry.attachment = first_attach_pos need_update = True if need_update: # fail to update post info is not that important if not self.UpdatePostEntry(post_entry, post_id, mode): Log.warn("fail to update post entry!")