Skip to content

Commit

Permalink
Merge pull request #65 from chinapnr/hujun_20180620
Browse files Browse the repository at this point in the history
Hujun 20180620
  • Loading branch information
itaa authored Jun 20, 2018
2 parents 35cd562 + a262c3c commit 18c6aed
Show file tree
Hide file tree
Showing 8 changed files with 217 additions and 27 deletions.
3 changes: 3 additions & 0 deletions docs/change_log.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
* issue ID use directly on github
* 36, common, edit function :meth:`fish_common.check_str()`, optimize, doc and unittest;
* 38, common, edit function :meth:`fish_common.find_files()`, optimize, doc and unittest;
* 37, date, edit function :meth:`fish_date.get_years()`, optimize, doc and unittest;
* 27, common, edit function :meth:`fish_common.hmac_sha256()`, optimize, doc and unittest;
* 61, date, edit function :meth:`fish_date.get_date_range()`, optimize, doc and unittest;

2018.6.6 v1.0.13
---------------------------
Expand Down
1 change: 1 addition & 0 deletions docs/fish_common.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
fish_common.splice_url_params
fish_common.check_str
fish_common.find_files
fish_common.hmac_sha256

.. automodule:: fish_common
:members:
9 changes: 9 additions & 0 deletions docs/fish_date.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
``fish_date`` 基本函数包
=============================

.. autosummary::
fish_date.get_date_range
fish_date.get_years

.. automodule:: fish_date
:members:
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ API 函数列表
fish_system
fish_file
fish_csv
fish_date
fish_logger


Expand Down
54 changes: 47 additions & 7 deletions fishbase/fish_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import uuid
import re
import hashlib
import hmac
import os
from collections import OrderedDict
import functools
Expand Down Expand Up @@ -174,7 +175,7 @@ def serialize_instance(obj):
return d


# 2018.5.26 v1.0.13 #19038, edit by David Yi
# 2018.5.26 v1.0.13 edit by David Yi,#19038
def get_uuid(kind):
"""
获得不重复的 uuid,可以是包含时间戳的 uuid,也可以是完全随机的;基于 Python 的 uuid 类进行封装和扩展;
Expand Down Expand Up @@ -230,7 +231,7 @@ def get_uuid(kind):
return str(uuid.uuid4())


# 2018.5.26 v1.0.13 #19038, edit by David Yi
# 2018.5.26 v1.0.13 edit by David Yi,#19038
get_time_uuid = functools.partial(get_uuid, udTime)


Expand Down Expand Up @@ -302,6 +303,7 @@ def get_cf_cache(self, cf, section, key):


# 2018.5.8 edit by David Yi, edit from Jia Chunying,#19026
# 2018.6.12 edit by Hu Jun, edit from Jia Chunying,#37
class GetMD5(object):
"""
计算普通字符串和一般的文件,对于大文件采取逐步读入的方式,也可以快速计算;基于 Python 的 hashlib.md5() 进行封装和扩展;
Expand All @@ -325,17 +327,19 @@ class GetMD5(object):
"""

@staticmethod
def string(s):
def string(s, salt=None):
"""
获取一个字符串的MD5值
:param:
* (string) str 需要进行 hash 的字符串
* (string) salt 随机字符串,默认为None
:return:
* (string) result 32位小写 MD5 值
"""
m = hashlib.md5()
m.update(s.encode('utf-8'))
s = s.encode('utf-8') + salt.encode('utf-8') if salt is not None else s.encode('utf-8')
m.update(s)
result = m.hexdigest()
return result

Expand Down Expand Up @@ -449,7 +453,7 @@ def splice_url_params(dic):
return url


# v1.0.13 #19043, edit by Hu Jun, edit by David Yi
# v1.0.13 edit by Hu Jun, edit by David Yi,#19043
def sorted_list_from_dict(p_dict, order=odASC):
"""
根据字典的 value 进行排序,并以列表形式返回
Expand Down Expand Up @@ -491,7 +495,7 @@ def sorted_list_from_dict(p_dict, order=odASC):
return o_list[::-1]


# v1.0.13 #36, edit by David Yi, edit by Hu Jun
# v1.0.13 edit by David Yi, edit by Hu Jun,#36
def check_str(p_str, check_style=charChinese):
"""
检查字符串是否含有指定类型字符
Expand Down Expand Up @@ -551,7 +555,7 @@ def check_str(p_str, check_style=charChinese):
raise TypeError(str(ex))


# v1.0.14 #38, edit by Hu Jun, edit from Jia Chunying
# v1.0.14 edit by Hu Jun, edit from Jia Chunying,#38
def find_files(path, exts=None):
"""
查找路径下的文件,返回指定类型的文件列表
Expand Down Expand Up @@ -590,3 +594,39 @@ def find_files(path, exts=None):
return [file for file in files_list if os.path.splitext(file)[-1] in exts]

return files_list


# v1.0.14 original by Jia Chunying, edit by Hu Jun, #27
def hmac_sha256(secret, message):
"""
hmac_sha256,通过秘钥获取消息的hash值
:param:
* secret: (string) 密钥
* message: (string) 消息输入
:return:
* hashed_str: (string) 长度为64的小写hex string 类型的hash值
举例如下::
print('--- hmac_sha256 demo---')
# 定义待hash的消息
message = 'Hello HMAC'
# 定义HMAC的秘钥
secret = '12345678'
hashed_str = hmac_sha256(secret, message)
print(hashed_str)
print('---')
执行结果::
--- hmac_sha256 demo---
5eb8bdabdaa43f61fb220473028e49d40728444b4322f3093decd9a356afd18f
---
"""
hashed_str = hmac.new(secret.encode('utf-8'),
message.encode('utf-8'),
digestmod=hashlib.sha256).hexdigest()
return hashed_str
111 changes: 91 additions & 20 deletions fishbase/fish_date.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,105 @@
# coding=utf-8

from datetime import datetime, date
from dateutil.relativedelta import relativedelta
from datetime import datetime
import calendar


# 2016.4.26
# 输入: date_kind, eg 'last month', 'this month'
# 输出: tuple, type datetime.date eg '2016-03-01' '2016-03-31'
def get_date_range(date_kind):
# v1.0.14 #61, edit by Hu Jun
def get_date_range(dates, separator='-'):
"""
获取某个月的日期范围,返回该月第一天和最后一天的字符串表示
:param:
* dates: (string 或者 datetime obj) 月份信息
* separator: (string) 分隔符,默认为 '-'
:return:
* first_day: (string) 该月份的第一天
* last_day: (string) 该月份的最后一天
today = datetime.today()
this_year = datetime.today().year
this_month = datetime.today().month
举例如下::
first_day = last_day = today
print('--- get_date_range demo ---')
now_time = datetime.now()
print(get_date_range(now_time))
print(get_date_range('201802',separator='/'))
print('---')
# 上个月
if date_kind == 'last month':
first_day = ((today - relativedelta(months=1)).replace(day=1)).date()
last_day = date(this_year, this_month, 1) - relativedelta(days=1)
执行结果::
# 本月
if date_kind == 'this month':
first_day = today.replace(day=1).date()
--- get_years demo ---
('2018-06-1', '2018-06-30')
('2018/02/1', '2018/02/28')
---
next_month = this_month + 1
if next_month == 13:
next_month = 1

this_month_last_day = date(this_year, next_month, 1) - relativedelta(days=1)
last_day = this_month_last_day
"""
if isinstance(dates, str) and dates.isdigit():
y = dates[:4]
m = dates[4:]
if (len(y) != 4) or (not 1 < int(m) < 12):
raise (ValueError("date must be a date string like '201806', but get {}".format(dates)))
elif hasattr(dates, 'year') and hasattr(dates, 'month'):
y = str(dates.year)
m = str(dates.month)
else:
raise (TypeError("date except a years string like '201806' or a object has 'year' "
"and 'month' attribute, but get a {}".format(type(dates))))

# set month to length 2 if month less than 10
m = '0'+m if len(m) != 2 else m

mr = calendar.monthrange(int(y), int(m))

first_day = separator.join([y, m, '1'])
last_day = separator.join([y, m, str(mr[1])])

return first_day, last_day


# v1.0.14 #37, edit by Hu Jun
def get_years(months=0, refer=None):
"""
获取基准时月份增量的年月
:param:
* months: (int) 月份增量,正数为往后年月,整数为往前年月
* refer: (datetime obj) datetime 对象,或者有month和year属性的实例,默认为当前时间
:return:
* result: (string) 年月字符串
举例如下::
print('--- get_years demo ---')
print(get_years(-5))
print(get_years(7, datetime.now()))
print('---')
执行结果::
--- get_years demo ---
201801
201901
---
"""
if refer is None:
refer = datetime.now()
# 计算当前总月份数
try:
months_count = refer.year * 12 + refer.month
except Exception:
raise TypeError('refer except {}, got an {}'.format(type(datetime.now()), type(refer)))

# 计算结果总月分数
months_count += months

y, m = divmod(months_count, 12)

# 将m的值转换为1-12
if m == 0:
y -= 1
m = 12

return ''.join(['%04d' % y, '%02d' % m])
20 changes: 20 additions & 0 deletions test/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ def test_md5_02(self):

assert GetMD5.file('./test/test_conf.ini') != 'bb7528c9778b2377e30b0f7e4c26fef0'

# 测试 GetMD5() tc
def test_md5_03(self):
salt = 'm4xV2yGFSn'
assert GetMD5.string('hello world!', salt) == '984d47991401fad7d920a30f715cfd22'

# 测试 if_json_contain() tc
def test_json_contain_01(self):

Expand Down Expand Up @@ -127,6 +132,9 @@ def test_get_uuid_01(self):
u2 = get_uuid(udRandom)

assert u1 != u2

u3 = get_uuid(10000)
assert u3 != u1

# test sorted_list_from_dict() tc
def test_sorted_list_from_dict_01(self):
Expand Down Expand Up @@ -154,10 +162,22 @@ def test_check_str_01(self):
assert check_str(chinese_str, check_style=charChinese) is True
assert check_str(non_num_str, check_style=charNum) is False
assert check_str(num_str, check_style=charNum) is True
assert check_str(non_num_str, check_style=10020) is False

if sys.version > '3':
chinese_str1 = u'有zhongwen'.encode('gbk')
with pytest.raises(TypeError):
check_str(chinese_str1, check_style=charChinese)

# test find_files() tc
def test_find_files_01(self):
path = './'
exts_list = ['.ini', '.py']

assert len(find_files(path)) >= len(find_files(path, exts=exts_list))

# test find_files() tc
def test_hmac_sha256_01(self):
message = 'Hello HMAC'
secret = '12345678'
assert hmac_sha256(secret, message) == '5eb8bdabdaa43f61fb220473028e49d40728444b4322f3093decd9a356afd18f'
45 changes: 45 additions & 0 deletions test/test_date.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# coding=utf-8
# fish_date.py 单元测试
# 2018.6.11 create by Hu Jun

import pytest
import sys
sys.path.append('../fishbase')
from fishbase.fish_date import *
import datetime


# 2018.6.11 v1.0.14 #37 create by Hu Jun
class TestFishDate(object):
# test get_years() tc
def test_get_years_01(self):
this_month = datetime.date(day=1, month=6, year=2018)

assert get_years(7, this_month) == '201901'
assert get_years(-5, this_month) == '201801'
assert get_years(-6, this_month) == '201712'

this_month1 = datetime.datetime.now()

y = this_month1.year
m = this_month1.month + 1
if m == 12:
y += 1
m = 1

assert get_years(1) == ''.join(['%04d' % y, '%02d' % m])

with pytest.raises(TypeError):
get_years(-5, 8)

def test_get_date_range_01(self):
this_month = datetime.date(day=1, month=2, year=2018)

assert get_date_range(this_month) == ('2018-02-1', '2018-02-28')
assert get_date_range('201802', separator='/') == ('2018/02/1', '2018/02/28')

with pytest.raises(ValueError):
get_date_range('2016798')

with pytest.raises(TypeError):
get_date_range('asdafsd')

0 comments on commit 18c6aed

Please sign in to comment.