def name(self, **kwargs): """str: The attribute name """ if "id" in kwargs and "attr" in kwargs: attr = fetch(kwargs["id"], kwargs["attr"]) elif "dataset" in kwargs: attr = fetch(self.id(**kwargs), self.attr_type) else: attr = self.attr long_version = kwargs.get("long") if long_version: name = attr["name_long"] else: name = attr["display_name"] if "display_name" in attr else attr[ "name"] text_only = kwargs.get("text_only", False) if not text_only and attr["id"] != self.attr["id"]: url_name = attr["url_name"] if "url_name" in attr and attr[ "url_name"] else attr["id"] name = u"<a href='{}'>{}</a>".format( url_for("profile.profile", attr_type=self.attr_type, attr_id=url_name), name) return name
def get_img(attr_kind, attr_id, mode="thumb"): attr = fetch(attr_id, attr_kind) def formatImage(attr, attr_type): image_attr = False if "image_link" in attr and attr["image_link"]: image_attr = attr else: parents = [ fetch(p["id"], attr_type) for p in get_parents(attr["id"], attr_type) ] for p in reversed(parents): if "image_link" in p and p["image_link"]: image_attr = p break if image_attr: return image_attr["id"] if attr_kind == "university" and not attr["image_link"]: if "msa" in attr and attr["msa"]: my_id = formatImage(fetch(attr["msa"], "geo"), "geo") attr_kind = "geo" else: my_id = formatImage(fetch("250000", "soc"), "soc") attr_kind = "soc" else: my_id = formatImage(attr, attr_kind) img_url = SPLASH_IMG_DIR.format(mode, attr_kind) + "{}.jpg".format(my_id) return redirect(img_url)
def image(self, **kwargs): attr_id = kwargs.get("attr_id", self.id(**kwargs)) attr = fetch(attr_id, self.attr_type) def formatImage(attr, attr_type): url = "/static/img/splash/{}/".format(attr_type) image_attr = False if "image_link" in attr and attr["image_link"]: image_attr = attr else: parents = [ fetch(p["id"], attr_type) for p in get_parents(attr["id"], attr_type) ] for p in reversed(parents): if "image_link" in p and p["image_link"]: image_attr = p break if image_attr: return { "url": "{}{}.jpg".format(url, image_attr["id"]), "link": image_attr["image_link"], "author": image_attr["image_author"], "meta": image_attr.get("image_meta", False) } if "image_link" in attr: if self.attr_type == "university" and attr["image_link"] == None: if "msa" in attr and attr["msa"] != None: return formatImage(fetch(attr["msa"], "geo"), "geo") else: return formatImage(fetch("250000", "soc"), "soc") return formatImage(attr, self.attr_type) return None
def sub(self, **kwargs): substitution = False key = kwargs.pop("key", "name") attr_id = self.id(**kwargs) attr_type = kwargs.get("attr_type", self.attr_type) if kwargs.get("dataset", False): if self.attr["id"] != attr_id: substitution = fetch(attr_id, self.attr_type) else: kwargs["data_only"] = True attrs = kwargs.pop("attrs", attr_type) subs = self.top(**kwargs) if "subs" in subs: subs = subs["subs"] if attr_type in subs and subs[attr_type] != attr_id: substitution = fetch(subs[attr_type], attrs) if key == "name": if substitution: return u"Based on data from {}".format(substitution[key]) else: return "" else: if substitution: return substitution[key] else: if "_iocode" in attr_type: return fetch(attr_id, attr_type)[key] return self.attr[key]
def __init__(self, attr_id, attr_type): self._id = attr_id self.attr_type = attr_type self.attr = {"id": "01000US", "name": "United States"} # read and update file_obj = self.open_file(attr_id) story_conf = yaml.load(file_obj) self.title = story_conf['title'] if 'title' in story_conf else '' self.description = story_conf['description'] if 'description' in story_conf else '' self.footnotes = story_conf['footnotes'] if 'footnotes' in story_conf else None self.date = story_conf['date'] if 'date' in story_conf else '' if not self.date: self.date = date_from_filename(attr_id) self._date_obj = parser.parse(self.date) self.date = self._date_obj.strftime("%B %-d, %Y") self.authors = story_conf['authors'] if 'authors' in story_conf else [] self.background_image = story_conf['background_image'] if 'background_image' in story_conf else None if self.background_image and "splash" in self.background_image: image_array = self.background_image.split("/") attr_type = image_array[4] attr_id = image_array[5].split(".")[0] attr = fetch(attr_id, attr_type) self.attr = fetch(attr_id, attr_type) tmp_obj = {"topics": story_conf['topics']} for i, t in enumerate(tmp_obj["topics"]): if "viz_url" in t: t["viz"] = Story.grab(t["viz_url"]) if "topic_url" in t: tmp_obj["topics"][i] = Story.grab(t["topic_url"], True) section = Section(self.load_yaml(tmp_obj), self) self.topics = section.topics
def get_img(attr_kind, attr_id, mode="thumb"): gobj = fetch(attr_id, attr_kind) my_id = gobj['id'] if 'image_link' not in gobj or not gobj['image_link']: parents = get_parents(attr_id, attr_kind) for p in reversed(parents): p = fetch(p["id"], attr_kind) if "image_link" in p and p['image_link']: my_id = p['id'] break static_root_url = SPLASH_IMG_DIR.format(mode, attr_kind) img_url = static_root_url.format(mode, attr_kind) + "{}.jpg".format(my_id) return redirect(img_url)
def sub(self, **kwargs): substitution = False key = kwargs.pop("key", "name") attr_id = self.id(**kwargs) attr_type = kwargs.get("attr_type", self.attr_type) original = fetch(self.attr["id"], self.attr_type) if kwargs.get("dataset", False): if self.attr["id"] != attr_id: substitution = fetch(attr_id, self.attr_type) else: kwargs["data_only"] = True attrs = kwargs.pop("attrs", attr_type) subs = self.top(**kwargs) if "subs" in subs: subs = subs["subs"] if attr_type in subs and subs[attr_type] != attr_id: substitution = fetch(subs[attr_type], attrs) if key == "name": if substitution: if original: if self.attr_type in SUMLEVELS and attr_type in SUMLEVELS: if "sumlevel" in original: origLevel = SUMLEVELS[self.attr_type][original["sumlevel"]]["label"] elif isinstance(original["level"], basestring): origLevel = "{} {} Group".format(original["level"].title(), DICTIONARY[self.attr_type]) else: level = str((original["level"] + 1) * 2) if self.attr_type == "cip" else str(original["level"]) origLevel = SUMLEVELS[self.attr_type][level]["label"] if "sumlevel" in substitution: subLevel = SUMLEVELS[attr_type][substitution["sumlevel"]]["label"] elif isinstance(substitution["level"], basestring): subLevel = "{} {} Group".format(substitution["level"].title(), DICTIONARY[attr_type]) else: level = str((substitution["level"] + 1) * 2) if attr_type == "cip" else str(substitution["level"]) subLevel = SUMLEVELS[attr_type][level]["label"] return u"The closest comparable data for the {0}{4}{1} is from the {2}{4}{3}.".format(origLevel, original["display_name"] if "display_name" in original else original[key], subLevel, substitution["display_name"] if "display_name" in substitution else substitution[key], " of " if attr_type == "geo" else " ") else: return u"The closest comparable data for {} is from {}.".format(original["display_name"] if "display_name" in original else original[key], substitution["display_name"] if "display_name" in substitution else substitution[key]) else: return u"Using data from {}.".format(substitution["display_name"] if "display_name" in substitution else substitution[key]) else: return "" else: if substitution: return substitution[key] else: if "_iocode" in attr_type: return fetch(attr_id, attr_type)[key] return self.attr[key]
def render_col(my_data, headers, col, url=False, dataset=False): value = my_data[headers.index(col)] if not value: return {"raw": None, "pretty": "N/A", "name": "N/A"} attr_type = col if "_iocode" in col: attr_type = "iocode" if dataset: alt_type = "{}_{}".format(dataset, attr_type) if alt_type in attr_cache: attr_type = alt_type if attr_type not in attr_cache: if isinstance(value, basestring): return_value = value else: # do simple number formating return_value = num_format(value, col) name = return_value else: # lookup the attr object and get the name attr = fetch(value, attr_type) url_name = attr["url_name"] if "url_name" in attr and attr["url_name"] else attr["id"] attr = attr["display_name"] if "display_name" in attr else attr["name"] name = attr if attr_type in PROFILES or attr_type in CROSSWALKS: attr = u"<a href='{}'>{}</a>".format(url_for("profile.profile", attr_type=attr_type, attr_id=url_name), attr) return_value = attr if url: return_value = u"<span class='stat-span' data-url='{}'>{}</span>".format(url, return_value) return {"raw": value, "pretty": return_value, "name": name}
def sumlevel(self, **kwargs): """str: A string representation of the depth type. """ attr_type = kwargs.get("attr_type", self.attr_type) attr_id = kwargs.get("attr_id", self.id(**kwargs)) requested_prefix = kwargs.get("prefix", False) if attr_type == "geo": if requested_prefix: name = SUMLEVELS["geo"][requested_prefix]["sumlevel"] else: prefix = attr_id[:3] if kwargs.get("dataset", False) == "chr" and prefix not in ["010", "040"]: prefix = "040" if kwargs.get("child", False) and "children" in SUMLEVELS["geo"][prefix]: prefix = SUMLEVELS["geo"][prefix]["children"] name = SUMLEVELS["geo"][prefix]["sumlevel"] if "plural" in kwargs: name = u"{}ies".format(name[:-1]) if name[-1] == "y" else u"{}s".format(name) return name elif attr_type == "cip": return str(len(attr_id)) else: return str(fetch(attr_id, attr_type)["level"])
def embed_view(attr_type, attr_id, section, topic): viz_only = request.args.get("viz", False) if not attr_type in PROFILES: abort(404) g.page_class = "{} embed".format(attr_type) topics = topic.split(",") required_namespaces = Profile.compute_namespaces(attr_type, section, topics) p = Profile(attr_id, attr_type, required_namespaces) section = p.section_by_topic(section, topics) if not section or not section.topics: abort(404) if "description" in section.topics[0]: section.meta = section.topics[0]["description"][0] else: section.meta = "" for t in section.topics: if viz_only: if "description" in t: del t["description"] if "stat" in t: del t["stat"] if "category" in t: del t["category"] g.compare = request.args.get("compare", False) if g.compare: g.compare = fetch(g.compare, attr_type) return render_template("profile/embed.html", profile=p, section=section)
def embed_view(attr_type, attr_id, section, topic): viz_only = request.args.get("viz", False) if not attr_type in PROFILES: abort(404) g.page_class = "{} embed".format(attr_type) topics = topic.split(",") required_namespaces = Profile.compute_namespaces(attr_type, section, topics) p = Profile(attr_id, attr_type, required_namespaces) section = p.section_by_topic(section, topics) if not section or not section.topics: abort(404) for t in section.topics: if viz_only: if "description" in t: del t["description"] if "stat" in t: del t["stat"] if "category" in t: del t["category"] g.compare = request.args.get("compare", False) if g.compare: g.compare = fetch(g.compare, attr_type) return render_template("profile/embed.html", profile = p, section = section)
def home(): g.page_type = "home" feed = [copy.copy(f) for f in HOMEFEED] for box in feed: if "featured" not in box: box["featured"] = False if "/profile/" in box["link"]: attr_type = box["link"].split("/")[2] attr_id = box["link"].split("/")[3] attr = fetch(attr_id, attr_type) box["subtitle"] = attr[ "display_name"] if "display_name" in attr else attr["name"] section = [ s for s in profile_cache[attr_type]["sections"] if s["anchor"] == box["section"] ][0] box["section"] = { "title": section["title"], "icon": "/static/img/icons/{}.svg".format(box["section"]) } sumlevel = attr["sumlevel"] if "sumlevel" in attr else attr["level"] if attr_type == "cip": sumlevel = (sumlevel + 1) * 2 sumlevel = str(sumlevel) sumlevel = SUMLEVELS[attr_type][sumlevel] sumlevel = sumlevel[ "shortlabel"] if "shortlabel" in sumlevel else sumlevel["label"] box["type"] = { "icon": "/static/img/icons/{}.svg".format(attr_type), "title": "Profile", "type": TYPEMAP[attr_type], "depth": sumlevel.replace("_", " ") } img_type = "feature" if box["featured"] else "thumb" box["image"] = "/static/img/{}/{}".format(img_type, attr["image_path"]) elif "/story/" in box["link"]: box["type"] = { "icon": "/static/img/icons/about.svg", "title": TYPEMAP["story"], "type": "story" } story = [ s for s in story_cache if s["story_id"] == box["link"].split("/")[2] ][0] box["image"] = story["background_image"] box["title"] = story["title"] box["subtitle"] = story["description"] box["author"] = "By {}".format(story["authors"][0]["name"]) elif "/map/" in box["link"]: box["type"] = { "icon": "/static/img/icons/demographics.svg", "title": TYPEMAP["map"], "type": "map" } box["viz"] = "geo_map" return render_template("general/home.html", feed=feed)
def attribute(self, **kwargs): key = kwargs.get("key") val = self.attr[key] if key == "opeid8": val = val[:-2] attr = kwargs.get("attr", False) if attr: val = self.make_links([fetch(val, attr)], attr) return val
def name(self, **kwargs): """str: The attribute name """ if "id" in kwargs and "attr" in kwargs: attr = fetch(kwargs["id"], kwargs["attr"]) elif "dataset" in kwargs: attr = fetch(self.id(**kwargs), self.attr_type) else: attr = self.attr long_version = kwargs.get("long") if long_version: name = attr["name_long"] else: name = attr["display_name"] if "display_name" in attr else attr["name"] text_only = kwargs.get("text_only", False) if not text_only and attr["id"] != self.attr["id"]: url_name = attr["url_name"] if "url_name" in attr and attr["url_name"] else attr["id"] name = u"<a href='{}'>{}</a>".format(url_for("profile.profile", attr_type=self.attr_type, attr_id=url_name), name) return name
def home(): g.page_type = "home" feed = [copy.copy(f) for f in HOMEFEED] for box in feed: if "featured" not in box: box["featured"] = False if "/profile/" in box["link"]: attr_type = box["link"].split("/")[2] attr_id = box["link"].split("/")[3] attr = fetch(attr_id, attr_type) box["subtitle"] = attr["display_name"] if "display_name" in attr else attr["name"] section = [s for s in profile_cache[attr_type]["sections"] if s["anchor"] == box["section"]][0] box["section"] = { "title": section["title"], "icon": "/static/img/icons/{}.svg".format(box["section"]) } sumlevel = attr["sumlevel"] if "sumlevel" in attr else attr["level"] if attr_type == "cip": sumlevel = (sumlevel + 1) * 2 sumlevel = str(sumlevel) sumlevel = SUMLEVELS[attr_type][sumlevel] sumlevel = sumlevel["shortlabel"] if "shortlabel" in sumlevel else sumlevel["label"] box["type"] = { "icon": "/static/img/icons/{}.svg".format(attr_type), "title": "Profile", "type": TYPEMAP[attr_type], "depth": sumlevel.replace("_"," ") } img_type = "feature" if box["featured"] else "thumb" box["image"] = "/static/img/{}/{}".format(img_type, attr["image_path"]) elif "/story/" in box["link"]: box["type"] = { "icon": "/static/img/icons/about.svg", "title": TYPEMAP["story"], "type": "story" } story = [s for s in story_cache if s["story_id"] == box["link"].split("/")[2]][0] box["image"] = story["background_image"] box["title"] = story["title"] box["subtitle"] = story["description"] box["author"] = "By {}".format(story["authors"][0]["name"]) elif "/map/" in box["link"]: box["type"] = { "icon": "/static/img/icons/demographics.svg", "title": TYPEMAP["map"], "type": "map" } box["viz"] = "geo_map" return render_template("general/home.html", feed=feed)
def nearby(self, **kwargs): if self.attr_type != "university": return [] attr_id = self.id(**kwargs) ids_only = kwargs.get("ids", False) endpoint = kwargs.get("endpoint", "nearby") url = "{}/attrs/{}/university/{}".format(API, endpoint, attr_id) try: results = requests.get(url).json() if "error" in results: results = requests.get(url.replace(endpoint, "nearby")).json() results = [r for r in datafold(results) if r["id"] != attr_id] sector = kwargs.get("sector", False) if sector: results = [fetch(r["id"], "university") for r in results] if sector == "private": results = [ r for r in results if str(r["sector"]) in ["2", "3", "5", "6", "8", "9"] ] else: results = [ r for r in results if str(r["sector"]) not in ["2", "3", "5", "6", "8", "9"] ] if ids_only: return ",".join([r["id"] for r in results]) return [fetch(r["id"], "university") for r in results] except ValueError: app.logger.info("STAT ERROR: {}".format(url)) if ids_only: return "" return []
def __init__(self, attr_id, attr_type, required_namespaces=None): """Initializes a new Profile class. Args: attr_id (str): The ID of the selected attribute attr_type (str): The attribute type of the profile. """ # set attr (using the fetch function) and attr_type self.attr = fetch(attr_id, attr_type) self.attr_type = attr_type self.variables = self.load_vars(required_namespaces) self.splash = Section(self.load_yaml(self.open_file("splash")), self)
def carnegie(self, **kwargs): parent = kwargs.get("parent", "carnegie_parent") carnegie_id = self.attr[parent] if not carnegie_id: carnegie_id = self.id(**kwargs) key = kwargs.get("key", "id") if key == "id": return carnegie_id else: carnegie_attr = fetch(carnegie_id, "university") if key == "name": return self.make_links([carnegie_attr]) else: return carnegie_attr[key]
def profile(attr_type, attr_id): if "_iocode" in attr_type: attr_type = "iocode" allowed_type = attr_type in PROFILES or attr_type in CROSSWALKS allowed_id = attr_type in attr_cache and attr_id in attr_cache[attr_type] if not allowed_type or not allowed_id: abort(404) if attr_type in CROSSWALKS: attr = attr_cache[attr_type][attr_id] crosswalks = acs_crosswalk(attr_type, attr_id) crosswalk_map = { "acs_occ": "soc", "acs_ind": "naics", "iocode": "naics" } crosswalk_labels = { "acs_occ": "ACS Occupation Code", "acs_ind": "ACS Industry Code", "iocode": "BEA I/O Code" } if len(crosswalks) > 1: g.page_type = "redirect" attr["type"] = crosswalk_labels[attr_type] return render_template("profile/redirect.html", attr=attr, crosswalks=crosswalks, crosswalk_type=crosswalk_map[attr_type]) return redirect( url_for('.profile', attr_type=crosswalk_map[attr_type], attr_id=crosswalks[0]["id"])) g.page_class = attr_type # pass id and type to Profile class p = profile_fetch(attr_type, attr_id) if request.args.get("json", False): return json.dumps(p, cls=MyEncoder) g.compare = request.args.get("compare", False) if g.compare: g.compare = fetch(g.compare, attr_type) # render the profile template and pass the profile to jinja return render_template("profile/index.html", profile=p)
def formatImage(attr, attr_type): image_attr = False if "image_link" in attr and attr["image_link"]: image_attr = attr else: parents = [ fetch(p["id"], attr_type) for p in get_parents(attr["id"], attr_type) ] for p in reversed(parents): if "image_link" in p and p["image_link"]: image_attr = p break if image_attr: return image_attr["id"]
def image(self): if "image_link" in self.attr: url = "/static/img/splash/{}/".format(self.attr_type) image_attr = False if self.attr["image_link"]: image_attr = self.attr else: parents = [fetch(p["id"], self.attr_type) for p in get_parents(self.attr["id"], self.attr_type)] for p in reversed(parents): if p["image_link"]: image_attr = p break if image_attr: return { "url": "{}{}.jpg".format(url, image_attr["id"]), "link": image_attr["image_link"], "author": image_attr["image_author"], "meta": image_attr.get("image_meta", False) } return None
def formatImage(attr, attr_type): url = "/static/img/splash/{}/".format(attr_type) image_attr = False if "image_link" in attr and attr["image_link"]: image_attr = attr else: parents = [ fetch(p["id"], attr_type) for p in get_parents(attr["id"], attr_type) ] for p in reversed(parents): if "image_link" in p and p["image_link"]: image_attr = p break if image_attr: return { "url": "{}{}.jpg".format(url, image_attr["id"]), "link": image_attr["image_link"], "author": image_attr["image_author"], "meta": image_attr.get("image_meta", False) }
def default_degree(self, **kwargs): if not self.common_degree: url = "{}/api?university={}&show=degree&required=grads_total&order=grads_total&sort=desc".format( API, self.attr["id"]) try: results = requests.get(url).json() if "error" in results: self.common_degree = "5" else: results = [r for r in datafold(results)] bachelor = [r for r in results if r["degree"] == "5"] if len(results) == 0 or len(bachelor) > 0: self.common_degree = "5" else: self.common_degree = results[0]["degree"] except ValueError: self.common_degree = "5" key = kwargs.get("key", False) if key: return fetch(self.common_degree, "degree")[key] return self.common_degree
def tileProfiles(profiles): for i, page in enumerate(profiles): show, slug = page.split("/") attr = fetch(slug, show) if show == "university": attr_id = attr["id"] if attr["image_link"] else attr["msa"] attr_type = "university" if attr["image_link"] else "geo" else: attr_id = attr["id"] attr_type = show profiles[i] = { "image": "/search/{}/{}/img".format(attr_type, attr_id), "link": "/profile/{}".format(page), "title": attr["display_name"] if "display_name" in attr else attr["name"], "new": 1 if show == "university" else 0 } return profiles
def tileProfiles(profiles): for i, page in enumerate(profiles): show, slug = page.split("/") attr = fetch(slug, show) attr_id = attr["id"] sumlevel = attr["sumlevel"] if "sumlevel" in attr else attr["level"] profiles[i] = { "image": "/search/{}/{}/img".format(show, attr_id), "link": "/profile/{}".format(page), "title": attr["display_name"] if "display_name" in attr else attr["name"], # "subtitle": SUMLEVELS[show][str(sumlevel)]["label"], "type": { "icon": "/static/img/icons/{}.svg".format(show), "title": SUMLEVELS[show][str(sumlevel)]["label"], "type": TYPEMAP[show], "depth": "{}".format(sumlevel).replace("_", " ") } } return profiles
def tileAPI(column): url = "{}{}&limit={}".format(API, column["url"], TILEMAX) r = requests.get(url).json() show = re.findall(r"show=([a-z_0-9]+)", url)[0] order = re.findall(r"order=([a-z_0-9]+)", url)[0] sumlevel = re.findall(r"sumlevel=([a-z_0-9]+)", url)[0] if show == "geo": sumlevel = sumlevelMap[sumlevel] data = datafold(r) for d in data: attr_id = d[show] attr = fetch(attr_id, show) slug = attr["url_name"] if attr["url_name"] else attr_id d["title"] = attr["display_name"] if "display_name" in attr else attr[ "name"] # d["subtitle"] = "{}: {}".format(DICTIONARY[order], num_format(d[order], order)) d["subtitle"] = SUMLEVELS[show][sumlevel]["label"] d["link"] = "/profile/{}/{}".format(show, slug) d["image"] = "/search/{}/{}/img".format(show, attr_id) d["type"] = { "icon": "/static/img/icons/{}.svg".format(show), "title": SUMLEVELS[show][sumlevel]["label"], "type": TYPEMAP[show], "depth": "{}".format(sumlevel).replace("_", " ") } column["icon"] = "/static/img/icons/{}.svg".format(show) column["data"] = data column["source"] = r["source"] if show in footMap: column["footer"] = { "link": "/search/?kind={}".format(show), "text": "{} more".format(num_format(footMap[show])) } return column
def profile(attr_type, attr_id): if "_iocode" in attr_type: attr_type = "iocode" allowed_type = attr_type in PROFILES or attr_type in CROSSWALKS allowed_id = attr_type in attr_cache and attr_id in attr_cache[attr_type] if not allowed_type or not allowed_id: abort(404) if attr_type in CROSSWALKS: attr = attr_cache[attr_type][attr_id] crosswalks = acs_crosswalk(attr_type, attr_id) crosswalk_map = {"acs_occ": "soc", "acs_ind": "naics", "iocode": "naics"} crosswalk_labels = {"acs_occ": "ACS Occupation Code", "acs_ind": "ACS Industry Code", "iocode": "BEA I/O Code"} if len(crosswalks) > 1: g.page_type = "redirect" attr["type"] = crosswalk_labels[attr_type] return render_template("profile/redirect.html", attr=attr, crosswalks=crosswalks, crosswalk_type=crosswalk_map[attr_type]) return redirect(url_for('.profile', attr_type=crosswalk_map[attr_type], attr_id=crosswalks[0]["id"])) g.page_class = attr_type # pass id and type to Profile class p = profile_fetch(attr_type, attr_id) if request.args.get("json", False): return json.dumps(p, cls=MyEncoder) g.compare = request.args.get("compare", False) if g.compare: g.compare = fetch(g.compare, attr_type) # render the profile template and pass the profile to jinja return render_template("profile/index.html", profile = p)
def stat(params, col="name", dataset=False, data_only=False, moe=False, truncate=0): # convert request arguments into a url query string rank = int(params.pop("rank", "1")) if "limit" in params: limit = int(params["limit"]) else: limit = 1 if rank > 1 and limit == 1: params["limit"] = rank query = RequestEncodingMixin._encode_params(params) url = "{}/api?{}".format(API, query) stat_url = "{}?{}&col={}&dataset={}&moe={}&rank={}".format(url_for("profile.statView"), query, col, dataset, moe, str(rank)) try: r = requests.get(url).json() except ValueError: app.logger.info("STAT ERROR: {}".format(url)) return { "url": stat_url, "value": "N/A" } if data_only: return r else: r = datafold(r) if dataset == "stat": if isinstance(r[0][col], list): r = [{params["show"]:x} for x in r[0][col]] col = "name" if len(r) == 0: return { "url": stat_url, "value": "N/A" } # if the output key is 'name', fetch attributes for each return and create an array of 'name' values # else create an array of the output key for each returned datapoint vals = [] show = params["show"].split(",")[-1] if col == "ratio": if limit == 1: vals = sorted([v for k, v in r[0].iteritems() if k in params["required"].split(",")], reverse=True) if vals[0] == 0 or vals[1] == 0: val = 0 else: val = vals[0]/vals[1] return num_format(val, key=col) else: denom = max([d[params["order"]] for d in r[1:]]) return num_format(r[0][params["order"]]/denom, key=col) if col == "diff": return num_format(r[0][params["order"]] - r[1][params["order"]], key=col) if col in COLMAP or "-" in col: vals = datapivot(r, col.split("-"), sort="desc") vals = [v for v in vals[rank - 1:limit]] if moe: top = [v["moe"] for v in vals] else: top = [v["name"] for v in vals] vals = [v["value"] for v in vals] else: if rank > 1: r = r[rank-1:] if moe: top = [d[moe] for d in r] elif col == "name": if dataset in ["acs", "pums"]: attr = "{}_{}".format(dataset, show) else: attr = show top = [fetch(d[show], attr) for d in r] if attr in PROFILES or attr in CROSSWALKS: top = [(t["id"], t["display_name"] if "display_name" in t else t[col], t["url_name"] if "url_name" in t and t["url_name"] else t["id"]) for t in top] top = [u"<a href='{}'>{}</a>".format(url_for("profile.profile", attr_type=attr, attr_id=t[2]), t[1]) if attr != "geo" or t[0][:3] != "140" else t[1] for t in top] else: top = [t["display_name"] if "display_name" in t else t[col] for t in top] elif col == "id": top = [d[show] for d in r] else: top = [d[col] for d in r] if col != "id": if moe: col = moe top = [num_format(t, col) if isinstance(t, (int, float)) else t for t in top] # coerce all values to strings top = [u"{}".format(t) if t != "" else u"N/A" for t in top] if col == "id": top = u",".join(top) else: num_items = len(top) if truncate and num_items > truncate: top, rest = top[:int(truncate)], top[int(truncate):] # now stringify top = u"{}; <a href='#' class='show-more pri-link'>& {} more</a>".format(u"; ".join(top), len(rest)) if len(rest) > 1: rest = u"; ".join(rest) else: rest = u"and {}".join(rest[-1]) top = u"<span>{}</span><span class='the_rest'>{}</span>".format(top, rest) else: if num_items > 1: top[-1] = u"and {}".format(top[-1]) if num_items == 2: top = u" ".join(top) else: top = u"; ".join(top) # otherwise, return the list joined with commans return { "url": stat_url, "value": top, "data": vals }
def __init__(self, config, profile, anchor=""): """Initializes a new Section class. Args: config (str): The parsed YAML string as a dict profile (Profile): The Profile class instance this Section will be a part of. """ # Set the attr and profile attributes self.attr = profile.attr self.attr_type = profile.attr_type self.anchor = anchor if "title" in config: self.title = config["title"] if "group" in config: self.group = config["group"] if "description" in config: self.description = config["description"] if not isinstance(self.description, list): self.description = [self.description] if "viz" in config: self.viz = Viz(config["viz"], profile=profile) if "topics" in config: self.topics = config["topics"] # filter out topics that are not appropriate for sumlevel self.topics = [t for t in self.topics if self.allowed_levels(t)] # loop through the topics for topic in self.topics: if "title" in topic: topic["title"] = self.tooltipify(topic["title"]) if "description" in topic: if not isinstance(topic["description"], list): topic["description"] = [topic["description"]] topic["description"] = [ self.tooltipify(desc) for desc in topic["description"] ] def getHighlight(viz_obj): ids = viz_obj["id"] if not isinstance(ids, list): ids = [ids] if profile.attr_type in ids: return self.attr["id"] else: return False if "stat" in topic: topic["stat"] = [ s for s in topic["stat"] if self.allowed_levels(s) ] for s in topic["stat"]: if "title" in s: s["title"] = self.tooltipify(s["title"]) # instantiate the "viz" config into an array of Viz classes if "viz" in topic: if not isinstance(topic["viz"], list): topic["viz"] = [topic["viz"]] topic["viz"] = [ v for v in topic["viz"] if self.allowed_levels(v) ] topic["viz"] = [ Viz(viz, getHighlight(viz), profile=profile) for viz in topic["viz"] ] if "miniviz" in topic: topic["miniviz"] = Viz(topic["miniviz"], getHighlight(topic["miniviz"]), profile=profile) # fill selector if present if "select" in topic: if isinstance(topic["select"]["data"], str): if "param" not in topic["select"]: topic["select"]["param"] = topic["select"]["data"] topic["select"]["data"] = [ v for k, v in attr_cache[topic["select"] ["data"]].iteritems() ] if "filter" in topic["select"] and topic["select"][ "filter"] in profile.variables: f = [ v[topic["select"]["param"]]["raw"] for v in profile.variables[topic["select"]["filter"]] ] topic["select"]["data"] = [ d for d in topic["select"]["data"] if d["id"] in f ] elif isinstance(topic["select"]["data"], list): topic["select"]["data"] = [ fetch(v, False) for v in topic["select"]["data"] ] if len(topic["select"]["data"]) < 2: del topic["select"] if "sections" in config: self.sections = config["sections"] if "stats" in config: self.stats = config["stats"]
def __init__(self, config, profile, anchor=""): """Initializes a new Section class. Args: config (str): The parsed YAML string as a dict profile (Profile): The Profile class instance this Section will be a part of. """ # Set the attr and profile attributes self.attr = profile.attr self.attr_type = profile.attr_type self.anchor = anchor if "title" in config: self.title = config["title"] if "group" in config: self.group = config["group"] if "description" in config: self.description = config["description"] if not isinstance(self.description, list): self.description = [self.description] if "viz" in config: self.viz = Viz(config["viz"], profile = profile) if "topics" in config: self.topics = config["topics"] # filter out topics that are not appropriate for sumlevel self.topics = [t for t in self.topics if self.allowed_levels(t)] # loop through the topics for topic in self.topics: if "title" in topic: topic["title"] = self.tooltipify(topic["title"]) if "description" in topic: if not isinstance(topic["description"], list): topic["description"] = [topic["description"]] topic["description"] = [self.tooltipify(desc) for desc in topic["description"]] def getHighlight(viz_obj): ids = viz_obj["id"] if not isinstance(ids, list): ids = [ids] if profile.attr_type in ids: return self.attr["id"] else: return False if "stat" in topic: topic["stat"] = [s for s in topic["stat"] if self.allowed_levels(s)] for s in topic["stat"]: if "title" in s: s["title"] = self.tooltipify(s["title"]) # instantiate the "viz" config into an array of Viz classes if "viz" in topic: if not isinstance(topic["viz"], list): topic["viz"] = [topic["viz"]] topic["viz"] = [v for v in topic["viz"] if self.allowed_levels(v)] topic["viz"] = [Viz(viz, getHighlight(viz), profile = profile) for viz in topic["viz"]] if "miniviz" in topic: topic["miniviz"] = Viz(topic["miniviz"], getHighlight(topic["miniviz"]), profile = profile) # fill selector if present if "select" in topic: if isinstance(topic["select"]["data"], str): if "param" not in topic["select"]: topic["select"]["param"] = topic["select"]["data"] topic["select"]["data"] = [v for k, v in attr_cache[topic["select"]["data"]].iteritems()] if "filter" in topic["select"] and topic["select"]["filter"] in profile.variables: f = [v[topic["select"]["param"]]["raw"] for v in profile.variables[topic["select"]["filter"]]] topic["select"]["data"] = [d for d in topic["select"]["data"] if d["id"] in f] elif isinstance(topic["select"]["data"], list): topic["select"]["data"] = [fetch(v, False) for v in topic["select"]["data"]] if len(topic["select"]["data"]) < 2: del topic["select"] if "sections" in config: self.sections = config["sections"] if "stats" in config: self.stats = config["stats"]
def ranks(self, **kwargs): ranks = int(kwargs.get("limit", 1)) col = kwargs.get("col") attr_type = kwargs.get("attr_type", self.attr_type) params = {} params[attr_type] = self.attr["id"] params["required"] = col params["show"] = kwargs.get("show", self.attr_type) params["year"] = kwargs.get("year", "latest") params["sumlevel"] = kwargs.get("sumlevel", self.sumlevel(**kwargs)) query = RequestEncodingMixin._encode_params(params) url = "{}/api?{}".format(API, query) try: rank = int(datafold(requests.get(url).json())[0][col]) except ValueError: app.logger.info("STAT ERROR: {}".format(url)) return "" del params[attr_type] params["limit"] = 1 params["order"] = col params["sort"] = "desc" if rank <= (ranks / 2 + 1): results = range(1, ranks + 1) else: query = RequestEncodingMixin._encode_params(params) url = "{}/api?{}".format(API, query) try: max_rank = int(datafold(requests.get(url).json())[0][col]) except ValueError: app.logger.info("STAT ERROR: {}".format(url)) return "" if rank > (max_rank - ranks / 2 - 1): results = range(max_rank - ranks + 1, max_rank + 1) else: results = range(int(math.ceil(rank - ranks / 2)), int(math.ceil(rank + ranks / 2) + 1)) prev = kwargs.get("prev", False) next = kwargs.get("next", False) if prev: if rank == results[0]: return "N/A" else: results = [results[results.index(rank) - 1]] if next: if rank == results[-1]: return "N/A" else: results = [results[results.index(rank) + 1]] key = kwargs.get("key", False) if key == "id" or key == "name": del params["limit"] params[col] = ",".join([str(r) for r in results]) query = RequestEncodingMixin._encode_params(params) url = "{}/api?{}".format(API, query) try: results = datafold(requests.get(url).json()) except ValueError: app.logger.info("STAT ERROR: {}".format(url)) return "" if key == "id": results = [d[params["show"]] for d in results] elif key == "name": return self.make_links([ fetch(d[params["show"]], params["show"]) for d in results ], params["show"]) return ",".join([str(r) for r in results])
def sector(self, **kwargs): if kwargs.get("text", False): return fetch(self.attr["sector"], "sector")["name"] return "private" if str(self.attr["sector"]) in [ "2", "3", "5", "6", "8", "9" ] else "public"
def parents(self, **kwargs): id_only = kwargs.get("id_only", False) limit = kwargs.pop("limit", None) attr_id = self.id(**kwargs) prefix = kwargs.get("prefix", None) if (prefix or limit) and id_only == False: top = get_parents(attr_id, self.attr_type) if prefix: top = [p for p in top if p["id"].startswith(prefix)] if limit: top = top[-int(limit):] top = self.make_links(top) return top if self.attr["id"] == "01000US": col = kwargs.get("col", False) if col: params = { "show": "geo", "required": col, "sumlevel": "state", "order": col, "sort": "desc", "year": "latest" } query = RequestEncodingMixin._encode_params(params) url = "{}/api?{}".format(API, query) try: results = [r for r in datafold(requests.get(url).json()) if r[col]] except ValueError: app.logger.info("STAT ERROR: {}".format(url)) return "" results = results[:2] + results[-2:] if id_only: return ",".join([r["geo"] for r in results]) else: return [fetch(r["geo"], "geo") for r in results] else: results = [ {"id": "04000US06", "name": "California", "url_name": "california"}, {"id": "04000US48", "name": "Texas", "url_name": "texas"}, {"id": "04000US36", "name": "New York", "url_name": "new-york"}, {"id": "16000US1150000", "name":"Washington D.C.", "url_name": "washington-dc"}, {"id": "16000US3651000", "name":"New York, NY", "url_name": "new-york-ny"}, {"id": "16000US0644000", "name":"Los Angeles, CA", "url_name": "los-angeles-ca"}, {"id": "16000US1714000", "name":"Chicago, IL", "url_name": "chicago-il"} ] if id_only: return ",".join([r["id"] for r in results]) else: return results results = [p for p in get_parents(attr_id, self.attr_type) if p["id"] != attr_id] results = self.get_uniques(results) for p in results: if self.attr_type == "geo": level = p["id"][:3] elif self.attr_type == "cip": level = str(len(p["id"])) else: level = str(fetch(p["id"], self.attr_type)["level"]) p["sumlevel"] = SUMLEVELS[self.attr_type][level]["label"] if prefix: results = [r for r in results if r["id"].startswith(prefix)] if limit: results = results[-int(limit):] if id_only: return ",".join([r["id"] for r in results]) else: return results
def parents(self, **kwargs): id_only = kwargs.get("id_only", False) limit = kwargs.pop("limit", None) attr_id = self.id(**kwargs) prefix = kwargs.get("prefix", None) if (prefix or limit) and id_only == False: top = get_parents(attr_id, self.attr_type) if prefix: top = [p for p in top if p["id"].startswith(prefix)] if limit: top = top[-int(limit):] top = self.make_links(top) return top if self.attr["id"] == "01000US": col = kwargs.get("col", False) if col: params = { "show": "geo", "required": col, "sumlevel": "state", "order": col, "sort": "desc", "year": "latest" } query = RequestEncodingMixin._encode_params(params) url = "{}/api?{}".format(API, query) try: results = [r for r in datafold(requests.get(url).json()) if r[col]] except ValueError: app.logger.info("STAT ERROR: {}".format(url)) return "" results = results[:2] + results[-2:] if id_only: return ",".join([r["geo"] for r in results]) else: return [fetch(r["geo"], "geo") for r in results] else: results = [ {"id": "04000US06", "name": "California", "url_name": "california"}, {"id": "04000US48", "name": "Texas", "url_name": "texas"}, {"id": "04000US36", "name": "New York", "url_name": "new-york"}, {"id": "16000US1150000", "name":"Washington D.C.", "url_name": "washington-dc"}, {"id": "16000US3651000", "name":"New York, NY", "url_name": "new-york-ny"}, {"id": "16000US0644000", "name":"Los Angeles, CA", "url_name": "los-angeles-ca"}, {"id": "16000US1714000", "name":"Chicago, IL", "url_name": "chicago-il"} ] if id_only: return ",".join([r["id"] for r in results]) else: return results results = [p for p in get_parents(attr_id, self.attr_type) if p["id"] != attr_id] results = self.get_uniques(results) if prefix: results = [r for r in results if r["id"].startswith(prefix)] if limit: results = results[-int(limit):] if id_only: return ",".join([r["id"] for r in results]) else: return results