Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Initial commit

  • Loading branch information...
commit a1349865288320e815f23ddd637f61a704868834 0 parents
Ricardo Garcia authored October 12, 2011

Showing 2 changed files with 123 additions and 0 deletions. Show diff stats Hide diff stats

  1. 3  README
  2. 120  steam_discounts
3  README
... ...
@@ -0,0 +1,3 @@
  1
+steam_discounts is a small command line application written in Python that will
  2
+print the current Steam discounts to your terminal so you don't have to clic
  3
+around the website.
120  steam_discounts
... ...
@@ -0,0 +1,120 @@
  1
+#!/usr/bin/env python
  2
+# -*- coding: utf-8 -*-
  3
+import HTMLParser
  4
+import htmlentitydefs
  5
+import re
  6
+import subprocess
  7
+import sys
  8
+import urllib
  9
+
  10
+class Entry(object):
  11
+	def __init__(self):
  12
+		self.title = ""
  13
+		self.orig_price = -1
  14
+		self.discount = -1
  15
+		self.price = -1
  16
+	
  17
+class DiscountsParser(HTMLParser.HTMLParser):
  18
+	def __init__(self):
  19
+		HTMLParser.HTMLParser.__init__(self)
  20
+
  21
+		self.current_entry_ = None
  22
+		self.entries_ = []
  23
+
  24
+		self.in_h4_ = False
  25
+		self.in_discount_pct_ = False
  26
+		self.in_tab_price_ = False
  27
+		self.in_strike_ = False
  28
+
  29
+	def handle_starttag(self, tag, attrs):
  30
+		attrs_map = dict(attrs)
  31
+
  32
+		if tag == 'h4':
  33
+			# First field to extract, hence new entry.
  34
+			self.in_h4_ = True
  35
+			self.current_entry_ = Entry()
  36
+
  37
+		elif tag == 'div':
  38
+			if attrs_map.get('class', '') == 'tab_discount discount_pct':
  39
+				self.in_discount_pct_ = True
  40
+			elif attrs_map.get('class', '') == 'tab_price':
  41
+				self.in_tab_price_ = True
  42
+
  43
+		elif tag == 'strike':
  44
+			self.in_strike_ = True
  45
+	
  46
+	def handle_endtag(self, tag):
  47
+		if tag == 'h4':
  48
+			self.in_h4_ = False
  49
+
  50
+		elif tag == 'div':
  51
+			if self.in_discount_pct_:
  52
+				self.in_discount_pct_ = False
  53
+			elif self.in_tab_price_:
  54
+				self.in_tab_price_ = False
  55
+				# This was the last field to extract.
  56
+				self.entries_.append(self.current_entry_)
  57
+
  58
+		elif tag == 'strike':
  59
+			self.in_strike_ = False
  60
+
  61
+	def handle_data(self, data):
  62
+		if self.in_h4_:
  63
+			self.current_entry_.title += data.strip().decode('utf-8')
  64
+		elif self.in_discount_pct_:
  65
+			self.current_entry_.discount = int(data.strip()[:-1])
  66
+		elif self.in_strike_:
  67
+			num = data.strip().replace(',', '.')
  68
+			if len(num) > 0:
  69
+				self.current_entry_.orig_price = float(num)
  70
+		elif self.in_tab_price_:
  71
+			# Note we only enter here if not in <strike>
  72
+			num = data.strip().replace(',', '.')
  73
+			if len(num) > 0:
  74
+				self.current_entry_.price = float(num)
  75
+	
  76
+	def handle_entityref(self, name):
  77
+		if self.in_h4_:
  78
+			self.current_entry_.title += unichr(htmlentitydefs.name2codepoint[name])
  79
+	
  80
+	def get_entries(self):
  81
+		return self.entries_
  82
+
  83
+if __name__ == '__main__':
  84
+	# Find the number of discounts first.
  85
+	stream = urllib.urlopen('http://store.steampowered.com/')
  86
+	page = stream.read()
  87
+	stream.close()
  88
+
  89
+	mo = re.search(r"javascript:PageTab\('Discounts', *\d+, *(\d+)", page)
  90
+	if mo is None:
  91
+		sys.exit('FATAL: unable to find the number of discounts')
  92
+	total_discounts = int(mo.group(1))
  93
+
  94
+	# Retrieve the discounts.
  95
+	stream = urllib.urlopen(
  96
+		'http://store.steampowered.com/search/tab?bHoverEnabled=true' +
  97
+		'&style=&navcontext=1_4_4_&tab=Discounts&start=0' +
  98
+		'&count=%d' % total_discounts)
  99
+	page = stream.read()
  100
+	stream.close()
  101
+
  102
+	discounts_parser = DiscountsParser()
  103
+	discounts_parser.feed(page)
  104
+
  105
+	# Print them on screen
  106
+	title_width = 40
  107
+	entries = discounts_parser.get_entries()
  108
+	child = subprocess.Popen(['less'], stdin=subprocess.PIPE)
  109
+	for e in entries:
  110
+		print >>child.stdin, (u'%s .%s %*.2f€ (%*.2f€ %d%%)' % (
  111
+			e.title[:title_width],
  112
+			'.' * (title_width - len(e.title)),
  113
+			6,
  114
+			e.price,
  115
+			6,
  116
+			e.orig_price,
  117
+			e.discount,
  118
+			)).encode('utf-8')
  119
+	child.stdin.close()
  120
+	child.wait()

0 notes on commit a134986

Please sign in to comment.
Something went wrong with that request. Please try again.