Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

160 lines (128 sloc) 4.881 kb
# -*- coding: utf-8 -*-
#Canto - ncurses RSS reader
# Copyright (C) 2008 Jack Miller <jack@codezen.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# Story is a slick little class. It's main purpose is to hold all of the data
# for each story, both content and state. To save memory, 0.7.0 will attempt to
# fetch data from disk if it's not held by default. A good example is
# description information which can take up kilobytes or megabytes of memory but
# are rarely used.
# Story doesn't care which feed or tag it's associated with. If you really want
# to get the feed, story["feed"] contains the unique URL, but you'd have to use
# the config to get the Feed() object. The only thing that the Story() gets from
# the feed is the get_ufp function that gets the feedparser dict from disk.
from const import STORY_SAVED, STORY_UPDATED
import cPickle
import fcntl
class Story():
def __init__(self, d, ufp_path, updated):
self.updated = updated
self.ufp_path = ufp_path
self.ondisk = None
self.d = d
self.sel = 0
self.in_reader = 0
def __eq__(self, other):
if self["id"] != other["id"]:
return 0
# The reason that we have to check for membership is
# that sometimes (like when writing to disk) it's convenient
# to compare against a dict in the feedparser block than
# another Story object. In all of these cases, the feeds
# are guaranteed to be the same anyway.
if "feed" in other and (self["feed"] != other["feed"]):
return 0
return 1
def __str__(self):
return self.d["title"] + " " + str(id(self))
# Where get_ufp reads the ufp from disk, this narrows that down to a
# particular feed entry.
def get_ufp_entry(self):
if not self.ufp_path:
return {}
try:
f = open(self.ufp_path, "r")
try:
fcntl.flock(f.fileno(), fcntl.LOCK_SH)
ufp = cPickle.load(f)
except:
return {}
finally:
fcntl.flock(f.fileno(), fcntl.LOCK_UN)
f.close()
except:
return {}
for ondisk in ufp["entries"]:
if ondisk["id"] == self["id"]:
break
else:
self.ondisk = None
self.ondisk = ondisk
def __getitem__(self, key):
if key in self.d:
return self.d[key]
# If the key isn't stored by default, get it from disk.
else:
if not self.ondisk:
self.get_ufp_entry()
if not self.ondisk:
return ""
if key in self.ondisk:
return self.ondisk[key]
return ""
def __setitem__(self, key, item):
self.d[key] = item
def __contains__(self, key):
if key in self.d:
return True
else:
if not self.ondisk:
self.get_ufp_entry()
if not self.ondisk:
return False
return key in self.ondisk
def was(self, tag):
return tag in self.d["canto_state"]
def set(self, tag):
if not tag in self.d["canto_state"]:
self.d["canto_state"].append(tag)
self.updated = STORY_UPDATED
def unset(self,tag):
if tag in self.d["canto_state"]:
self.d["canto_state"].remove(tag)
self.updated = STORY_UPDATED
# These are separate from the was/set/unset since the selected status isn't
# stored in the ufp.
def selected(self):
return self.sel
def select(self):
self.sel = 1
def unselect(self):
self.sel = 0
def get_text(self):
if "content" in self:
for c in self["content"]:
if "type" in c and "text" in c["type"]:
return c["value"]
return self["description"]
def get_type(self):
if "content" in self:
for c in self["content"]:
if "type" in c and "text" in c["type"]:
return c["type"]
if "summary_detail" in self and "type" in self["summary_detail"]:
return self["summary_detail"]["type"]
return "text/html"
def get_title_type(self):
if "title_detail" in self and "type" in self["title_detail"]:
return self["title_detail"]["type"]
return "text/html"
# Free makes the Story() forget all of the uncommon items. Should be called
# after anything that could cause Story() to fetch items (ie. in the
# Renderer hooks).
def free(self):
if self.ondisk:
self.ondisk = None
Jump to Line
Something went wrong with that request. Please try again.