def increment_counter(self): """ Increment pastes counter. It uses a lock file to prevent multi access to the file. """ path = settings.PASTE_FILES_ROOT counter_file = os.path.join(path, 'counter') lock_file = os.path.join(path, 'counter.lock') # TODO : change lock implementation to use the lockfile lib # https://pypi.python.org/pypi/lockfile # The current lock implementation sucks. It skips some increment, and # still allows race conditions. if not os.path.isfile(lock_file): try: # Aquire lock file with open(lock_file, "w") as flock: flock.write('lock') # Read the value from the counter try: with open(counter_file, "r") as fcounter: counter_value = int(fcounter.read(50)) + 1 except (ValueError, IOError, OSError): counter_value = 1 # write new value to counter with open(counter_file, "w") as fcounter: fcounter.write(str(counter_value)) finally: # remove lock file os.remove(lock_file)
def increment_counter(self): """ Increment pastes counter. It uses a lock file to prevent multi access to the file. """ path = settings.PASTE_FILES_ROOT counter_file = os.path.join(path, 'counter') lock = lockfile.LockFile(counter_file) with lock: # Read the value from the counter try: with open(counter_file, "r") as fcounter: counter_value = int(fcounter.read(50)) + 1 except (ValueError, IOError, OSError): counter_value = 1 # write new value to counter with open(counter_file, "w") as fcounter: fcounter.write(str(counter_value))
def get_pastes_count(cls): """ Return the number of created pastes. (must have option DISPLAY_COUNTER enabled for the pastes to be be counted) """ counter_file = os.path.join(settings.PASTE_FILES_ROOT, 'counter') try: count = int(open(counter_file).read(50)) except (IOError, OSError): count = 0 return '{0:,}'.format(count)
def load_from_file(cls, path): """ Return an instance of the paste object with the content of the given file. """ try: with open(path) as paste: uuid = os.path.basename(path) expiration = next(paste).strip() content = next(paste).strip() if "burn_after_reading" not in expiration: expiration = datetime.strptime(expiration, '%Y-%m-%d %H:%M:%S.%f') except StopIteration: raise TypeError(to_ascii('File %s is malformed' % path)) except (IOError, OSError): raise ValueError(to_ascii('Can not open paste from file %s' % path)) return Paste(uuid=uuid, expiration=expiration, content=content)
def save(self): """ Save the content of this paste to a file. """ head, tail = self.uuid[:2], self.uuid[2:4] # the static files are saved in project_dir/static/xx/yy/uuid # xx and yy are generated from the uuid (see get_path()) # we need to check if they are created before writting # but since we want to prevent to many writes, we create # an in memory cache that will hold the result of this check fo # each worker. If the dir is not in cache, we check the FS, and # if the dir is not in there, we create the dir if head not in self.DIR_CACHE: self.DIR_CACHE.add(head) if not os.path.isdir(self.build_path(head)): os.makedirs(self.build_path(head, tail)) self.DIR_CACHE.add((head, tail)) if (head, tail) not in self.DIR_CACHE: path = self.build_path(head, tail) self.DIR_CACHE.add((head, tail)) if not os.path.isdir(path): os.mkdir(path) # add a timestamp to burn after reading to allow # a quick period of time where you can redirect to the page without # deleting the paste if "burn_after_reading" == self.expiration: expiration = self.expiration + '#%s' % datetime.now( ) # TODO: use UTC dates expiration = self.expiration else: expiration = as_unicode(self.expiration) # write the paste with open(self.path, 'w') as f: f.write(expiration + '\n') f.write(self.content + '\n') return self
def save(self): """ Save the content of this paste to a file. """ head, tail = self.uuid[:2], self.uuid[2:4] # the static files are saved in project_dir/static/xx/yy/uuid # xx and yy are generated from the uuid (see get_path()) # we need to check if they are created before writting # but since we want to prevent to many writes, we create # an in memory cache that will hold the result of this check fo # each worker. If the dir is not in cache, we check the FS, and # if the dir is not in there, we create the dir if head not in self.DIR_CACHE: self.DIR_CACHE.add(head) if not os.path.isdir(self.build_path(head)): os.makedirs(self.build_path(head, tail)) self.DIR_CACHE.add((head, tail)) if (head, tail) not in self.DIR_CACHE: path = self.build_path(head, tail) self.DIR_CACHE.add((head, tail)) if not os.path.isdir(path): os.mkdir(path) # add a timestamp to burn after reading to allow # a quick period of time where you can redirect to the page without # deleting the paste if "burn_after_reading" == self.expiration: expiration = self.expiration + '#%s' % datetime.now() # TODO: use UTC dates expiration = self.expiration else: expiration = as_unicode(self.expiration) # write the paste with open(self.path, 'w') as f: f.write(expiration + '\n') f.write(self.content + '\n') return self