class OperatingRevenueFeedBuilder: def __init__(self): self.account_synonym = AccountSynonym() self.date_utils = DateUtils() def build(self, dao): tuple_feed = self.__build_tuple(dao) return OperatingRevenueFeed(tuple_feed) def __build_tuple(self, dao): feed = [] release_date = self.date_utils.get_last_date_of_month(dao.get_date()) stock_symbol = dao.get_stock_symbol() for account, value in dao.get_row_list(): if self.account_synonym.get(account) == u"當月營收": entry = { "release_date": release_date, "stock_symbol": stock_symbol, "stmt_date": self.date_utils.get_last_date_of_month(release_date), "account": u"當月營收", "account_order": 1, "value": value, } feed.append(entry) return tuple(feed)
class OperatingRevenueSummaryFeedBuilder: def __init__(self): self.date_utils = DateUtils() def build(self, dao): tuple_feed = self.__build_tuple(dao) return OperatingRevenueFeed(tuple_feed) def __build_tuple(self, dao): feed = [] stmt_date = self.date_utils.get_last_date_of_month(dao.get_stmt_date()) release_date = dao.get_release_date() for row in dao.get_row_list(): stock_symbol = row[0] this_month_value = row[2] last_month_value = row[3] entry = { "release_date": release_date, "stock_symbol": stock_symbol, "stmt_date": stmt_date, "account": u"當月營收", "account_order": 1, "value": this_month_value, } feed.append(entry) entry = { "release_date": release_date, "stock_symbol": stock_symbol, "stmt_date": self.date_utils.get_last_date_of_prev_month(stmt_date), "account": u"上月營收", "account_order": 2, "value": last_month_value, } feed.append(entry) return tuple(feed)
class DateBuilder(): def __init__(self): self.date_utils = DateUtils() def build(self, local_string): try: m = re.search(u'^(\d{4})年(\d+)月(\d+)日$', local_string) year = int(m.group(1)) month = int(m.group(2)) day = int(m.group(3)) return datetime.date(year, month, day) except AttributeError: return self.__build_step_1(local_string) def __build_step_1(self, local_string): try: m = re.search(u'^(\d{2,3})年(\d+)月(\d+)日$', local_string) year = int(m.group(1)) + 1911 # expect roc era month = int(m.group(2)) day = int(m.group(3)) return datetime.date(year, month, day) except AttributeError: return self.__build_step_2(local_string) def __build_step_2(self, local_string): try: m = re.search('^(\d{4})/(\d+)/(\d+)$', local_string) year = int(m.group(1)) month = int(m.group(2)) day = int(m.group(3)) return datetime.date(year, month, day) except AttributeError: return self.__build_step_3(local_string) def __build_step_3(self, local_string): try: m = re.search('^(\d{2,3})/(\d+)/(\d+)$', local_string) year = int(m.group(1)) + 1911 # expect roc era month = int(m.group(2)) day = int(m.group(3)) return datetime.date(year, month, day) except AttributeError: return self.__build_step_4(local_string) def __build_step_4(self, local_string): try: m = re.search('^(\d{2,3})$', local_string) year = int(m.group(1)) + 1911 # expect roc era return datetime.date(year, 12, 31) except AttributeError: return self.__build_step_5(local_string) def __build_step_5(self, local_string): m = re.search(u'^民國(\d{2,3})年(\d+)月$', local_string) year = int(m.group(1)) + 1911 # expect roc era month = int(m.group(2)) day = self.date_utils.get_last_day_of_month(year, month) return datetime.date(year, month, day)
class DividendPolicyFeedBuilder: def __init__(self): self.date_utils = DateUtils() def build(self, dao): tuple_feed = self.__build_tuple(dao) return DividendPolicyFeed(tuple_feed) def __build_tuple(self, dao): feed = [] stock_symbol = dao.get_stock_symbol() release_date = self.date_utils.now_date() for row in dao.get_row_list(): stmt_date = row[0] cash_dividend = row[1] # 現金股利 stock_dividend_from_retained_earnings = row[2] # 盈餘配股 stock_dividend_from_capital_reserve = row[3] # 公積配股 employee_stock_bonuses_ratio = row[6] # 員工配股率% entry = { "release_date": release_date, "stock_symbol": stock_symbol, "stmt_date": stmt_date, "account": u"現金股利", "account_order": 1, "value": cash_dividend, } feed.append(entry) entry = { "release_date": release_date, "stock_symbol": stock_symbol, "stmt_date": stmt_date, "account": u"盈餘配股", "account_order": 2, "value": stock_dividend_from_retained_earnings, } feed.append(entry) entry = { "release_date": release_date, "stock_symbol": stock_symbol, "stmt_date": stmt_date, "account": u"公積配股", "account_order": 3, "value": stock_dividend_from_capital_reserve, } feed.append(entry) entry = { "release_date": release_date, "stock_symbol": stock_symbol, "stmt_date": stmt_date, "account": u"員工配股率", "account_order": 4, "value": employee_stock_bonuses_ratio, } feed.append(entry) return tuple(feed)
class CapitalIncreaseHistoryFeedBuilder(): def __init__(self): self.date_utils = DateUtils() def build(self, dao): tuple_feed = self.__build_tuple(dao) return CapitalIncreaseHistoryFeed(tuple_feed) def __build_tuple(self, dao): feed = [] stock_symbol = dao.get_stock_symbol() release_date = self.date_utils.now_date() for row in dao.get_row_list(): stmt_date = row[0] capital_increase_by_cash = row[1] capital_increase_by_earnings = row[3] capital_increase_by_surplus = row[5] entry = { 'release_date' : release_date, 'stock_symbol' : stock_symbol, 'stmt_date' : stmt_date, 'account' : u'現金增資', 'account_order' : 1, 'value' : capital_increase_by_cash } feed.append(entry) entry = { 'release_date' : release_date, 'stock_symbol' : stock_symbol, 'stmt_date' : stmt_date, 'account' : u'盈餘轉增資', 'account_order' : 2, 'value' : capital_increase_by_earnings } feed.append(entry) entry = { 'release_date' : release_date, 'stock_symbol' : stock_symbol, 'stmt_date' : stmt_date, 'account' : u'公積及其他', 'account_order' : 3, 'value' : capital_increase_by_surplus } feed.append(entry) return tuple(feed)
class TupleFeedBuilder(): def __init__(self): self.date_utils = DateUtils() def build(self, dao): feed = [] release_date = self.date_utils.now_date() stock_symbol = dao.get_stock_symbol() column_name_list = dao.get_column_name_list() stmt_date_list = column_name_list[1:] # the first column is account stmt_date_list = self.__flatten_stmt_date_list(stmt_date_list) stmt_date_len = len(stmt_date_list) account_order = 1 for row in dao.get_row_list(): account = row[0] number_list = row[1:] number_len = len(number_list) for i in range(stmt_date_len): stmt_date = stmt_date_list[i] value = number_list[i] if i < number_len else None entry = { 'release_date' : release_date, 'stock_symbol' : stock_symbol, 'stmt_date' : stmt_date, 'account' : account, 'account_order' : account_order, 'value' : value } feed.append(entry) account_order += 1 return tuple(feed) # flatten to date if stmt_date_list if date period list def __flatten_stmt_date_list(self, stmt_date_list): # if date period, we flatten to end date because begin date is always # the first date of this year. if len(stmt_date_list) > 0 and isinstance(stmt_date_list[0], tuple): return [stmt_date[1] for stmt_date in stmt_date_list] else: return stmt_date_list
class OperatingRevenueSummaryAssembler: def __init__(self): self.content_screener = ContentScreener() self.date_utils = DateUtils() self.string_utils = StringUtils() def assemble(self, param): content, date = param["content"], param["date"] self.content_screener.screen(param) stmt_date = self.date_utils.get_last_date_of_month(date) column_name_list, row_list, release_date = self.__assemble_summary(content) return OperatingRevenueSummaryDao(column_name_list, row_list, stmt_date, release_date) def __assemble_summary(self, html_object): try: return AriesParser().parse(html_object) except AssertionError: return self.__assemble_summary_step_1(html_object) def __assemble_summary_step_1(self, html_object): try: return TaurusParser().parse(html_object) except AssertionError: return self.__assemble_summary_step_2(html_object) def __assemble_summary_step_2(self, html_object): try: return GeminiParser().parse(html_object) except AssertionError: return self.__assemble_summary_step_3(html_object) def __assemble_summary_step_3(self, html_object): try: return CancerParser().parse(html_object) except AssertionError: return LeoParser().parse(html_object)
def __init__(self): self.date_utils = DateUtils()
def __init__(self): self.content_screener = ContentScreener() self.date_utils = DateUtils() self.string_utils = StringUtils()
def __init__(self): self.account_synonym = AccountSynonym() self.date_utils = DateUtils()
def setUp(self): self.date_utils = DateUtils()
class DateUtilsTest(unittest.TestCase): def setUp(self): self.date_utils = DateUtils() def tearDown(self): self.date_utils = None def test_get_last_date_of_month(self): actual = self.date_utils.get_last_date_of_month(datetime.date(2010, 1, 1)) expected = datetime.date(2010, 1, 31) self.assertEqual(actual, expected) def test_get_last_date_of_prev_month(self): actual = self.date_utils.get_last_date_of_prev_month(datetime.date(2010, 1, 1)) expected = datetime.date(2009, 12, 31) self.assertEqual(actual, expected) def test_get_last_date_of_quarter(self): actual = self.date_utils.get_last_date_of_quarter(datetime.date(2010, 1, 1)) expected = datetime.date(2010, 3, 31) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_quarter(datetime.date(2010, 3, 31)) expected = datetime.date(2010, 3, 31) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_quarter(datetime.date(2010, 4, 1)) expected = datetime.date(2010, 6, 30) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_quarter(datetime.date(2010, 6, 30)) expected = datetime.date(2010, 6, 30) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_quarter(datetime.date(2010, 7, 1)) expected = datetime.date(2010, 9, 30) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_quarter(datetime.date(2010, 9, 30)) expected = datetime.date(2010, 9, 30) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_quarter(datetime.date(2010, 10, 1)) expected = datetime.date(2010, 12, 31) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_quarter(datetime.date(2010, 12, 31)) expected = datetime.date(2010, 12, 31) self.assertEqual(actual, expected) def test_get_last_date_of_next_quarter(self): actual = self.date_utils.get_last_date_of_next_quarter(datetime.date(2010, 1, 1)) expected = datetime.date(2010, 6, 30) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_next_quarter(datetime.date(2010, 3, 31)) expected = datetime.date(2010, 6, 30) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_next_quarter(datetime.date(2010, 4, 1)) expected = datetime.date(2010, 9, 30) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_next_quarter(datetime.date(2010, 6, 30)) expected = datetime.date(2010, 9, 30) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_next_quarter(datetime.date(2010, 7, 1)) expected = datetime.date(2010, 12, 31) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_next_quarter(datetime.date(2010, 9, 30)) expected = datetime.date(2010, 12, 31) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_next_quarter(datetime.date(2010, 10, 1)) expected = datetime.date(2011, 3, 31) self.assertEqual(actual, expected) actual = self.date_utils.get_last_date_of_next_quarter(datetime.date(2010, 12, 31)) expected = datetime.date(2011, 3, 31) self.assertEqual(actual, expected) def test_range_date_by_month(self): actual = self.date_utils.range_date_by_month(datetime.date(2010, 9, 1), datetime.date(2011, 3, 15)) expected = [ datetime.date(2010, 9, 30), datetime.date(2010, 10, 31), datetime.date(2010, 11, 30), datetime.date(2010, 12, 31), datetime.date(2011, 1, 31), datetime.date(2011, 2, 28), datetime.date(2011, 3, 31), ] self.assertEqual(actual, expected) def test_range_date_by_quarter(self): actual = self.date_utils.range_date_by_quarter(datetime.date(2010, 9, 1), datetime.date(2011, 3, 15)) expected = [ datetime.date(2010, 9, 30), datetime.date(2010, 12, 31), datetime.date(2011, 3, 31), ] self.assertEqual(actual, expected)