urlwatch urlwatch

 

前面都是一些说明和变量注释,从53行开始,把一些常用的方法于函数过了一遍。

# os.path.expanduser调用后,返回的urlwatch_dir就是~/urlwatcher目录

# 通过调用join方法可以使得路径的分隔符不受系统限制,win上是'/',unix是'/'
 53 urlwatch_dir = os.path.expanduser(os.path.join('~', '.'+pkgname))
 54 urls_txt = os.path.join(urlwatch_dir, 'urls.txt')
 55 cache_dir = os.path.join(urlwatch_dir, 'cache')
 56 scripts_dir = os.path.join(urlwatch_dir, 'lib')
 57 hooks_py = os.path.join(scripts_dir, 'hooks.py')

 58

# sys.argv[0]传入的脚本名称
# os.path.abspath取脚本的绝对路径
# os.path.dirname取除去文件名后的目录名
# os.path.split分隔文件名和目录名,用个tuple来装,bindir是末尾的文件目录

 59 # Check if we are installed in the system already
 60 (prefix, bindir) = os.path.split(os.path.dirname(os.path.abspath(sys.argv[0])))

 

# sys.path.append是将目录加入python系统目录,使其能够访问lib目录里的文件

 68     sys.path.append(os.path.join(prefix, bindir, 'lib'))

# logging日志模块
# 设置日志级别

 94 log = logging.getLogger(pkgname)
 95 log.setLevel(logging.DEBUG)

# 添加空handler,不知有什么用,待查

101 log.addHandler(NullHandler())

# 在type.upper()和url之间插入“:“

114     summary_txt = ': '.join((type.upper(), url))

# main开始

130 if __name__ == '__main__':

# 取当前系统时间

131     start = datetime.datetime.now()

 

再接下来就是郁闷我很久的optparse

# 先出个OptionParser,附上说明

134     parser = optparse.OptionParser(usage='%%prog [options]/n/n%s' % __doc__.    strip(), version=pkgname+' '+__version__)

# 如果出现传入参数-v,等价于options.verbose=true
135     parser.add_option('-v', '--verbose', action='store_true', dest='verbose'    , help='Show debug/log output')
# 出现传入参数--urls, 等价于options.urls为--urls后紧跟的参数
# metavar有助于提醒用户,该命令行参数所期待的参数,如 metavar="mode"(找了很久都没找到metavar的意思,这个是从别的文章扒下来的),在传入help参数后此行的提示就应该为:

#         --urls=FILE        Read     URLs from the specified file

136     parser.add_option('', '--urls', dest='urls', metavar='FILE', help='Read     URLs from the specified file')
    # 设置parse的默认值
140     parser.set_defaults(verbose=False, display_errors=False)
    # 解析args
142     (options, args) = parser.parse_args(sys.argv)

 

# 解析完args后,接下来就是对args中的各个参数的生效设定以及合法性校验

# 首先是verbose,如果传入参数带有--verbose的话,那么创建一个StreamHandler,设置其级别为DEBUG,这样运行程序的日志就都会出现在console上了,方便用于调试

143     if options.verbose:

144         console = logging.StreamHandler()
145         console.setLevel(logging.DEBUG)
146         formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
147         console.setFormatter(formatter)
148         log.addHandler(console)
149         log.info('turning on verbose logging mode')

 

# 接下来是display_errors,设置显示错误标志位

151     if options.display_errors:
152         log.info('turning display of errors ON')
153         display_errors = True

 

# 再下来是urls,判断传入的urls参数是否为文件,是:打印日志,否:程序退出

155     if options.urls:
156         if os.path.isfile(options.urls):
157             urls_txt = options.urls
158             log.info('using %s as urls.txt' % options.urls)

159         else:
160             log.error('%s is not a file' % options.urls)
161             print 'Error: %s is not a file' % options.urls
162             sys.exit(1)

 

# 最后是hooks,与urls一致

164     if options.hooks:
165         if os.path.isfile(options.hooks):
166             hooks_py = options.hooks
167             log.info('using %s as hooks.py' % options.hooks)
168         else:
169             log.error('%s is not a file' % options.hooks)
170             print 'Error: %s is not a file' % options.hooks
171             sys.exit(1)

 

# 这段程序显而易见,偷懒不说了

173     # Created all needed folders
174     for needed_dir in (urlwatch_dir, cache_dir, scripts_dir):
175         if not os.path.isdir(needed_dir):
176             os.makedirs(needed_dir)

 

# 以下这段也不说了,值得一说的是shutil,又学到个新模块,shutil.copy(srt, dst)等价于sh中的cp srt dst,而shutil.copy2(srt, dst)等价于cp -p srt dst,拷贝的不仅是文件,还包括文件的属性(ownership,mode,timestamps ==)

178     # Check for required files
179     if not os.path.isfile(urls_txt):

···

192         if os.path.exists(urls_txt_example) and not os.path.exists(urls_txt_fn):
193             shutil.copy(urls_txt_example, urls_txt_fn)
194         if not options.hooks and os.path.exists(hooks_py_example) and not os.pat    h.exists(hooks_py_fn):
195             shutil.copy(hooks_py_example, hooks_py_fn)

 

# 再往下,hooks_py其实里面只需要定义一个过滤器函数filter,可以利用正则式从结果中筛选需要的信息

206     if os.path.exists(hooks_py):
207         log.info('using hooks.py from %s' % hooks_py)


# 通过imp.load_source,将hooks_py导入工程,使得接下来能够使用hooks_py中的方法

208         hooks = imp.load_source('hooks', hooks_py)

# 判断filter是否为hooks模块的属性

209         if hasattr(hooks, 'filter'):
210             log.info('found and enabled filter function from hooks.py')
211             filter = hooks.filter
212         else:
213             log.warning('hooks.py has no filter function - ignoring')

# lambda在此等价于def filter(x, y):return y,在这种情况下,filter就等于传入的y参数

214             filter = lambda x, y: y
215     else:
216         log.info('not using hooks.py (file not found)')
217         filter = lambda x, y: y

 

# 这段是处理文件名的,将缓存文件夹中的文件名转为sha1加密后的密文,为了防止混淆?

# 用到了hashlib,hashlib.new('sha1')也可以等价于hashlib.sha1(),试了下,两种功能一样,应该是由于python的版本不同造成的差异吧,之后的处理都一样,update,digest,只不过用了hexdigest,用十六进制表示加密密文

219     for url in (x for x in open(urls_txt).read().splitlines() if not (x.startswi    th('#') or x.strip()=='')):
220         log.info('processing URL: %s' % url)
221         if have_hashlib:
222             sha_hash = hashlib.new('sha1')
223             sha_hash.update(url)
224         else:
225             sha_hash = sha.new(url)
226         filename = os.path.join(cache_dir, sha_hash.hexdigest())

 

# 终于出现try了,urlwatch真正干活的东东就只两个,urllib2.urlopen和difflib.unified_diff,urllib这个东西比较庞大,以后再研究。

# 程序调用了Request于urlopen去获取页面,然后通过difflib.unified_diff去比较当前获取页面的内容与缓存文件的内容是否不同,风格类似sh中的diff

227         try:
228             request = urllib2.Request(url, None, headers)
229             data = filter(url, urllib2.urlopen(request).read())
230             if os.path.exists(filename):
231                 log.info('%s exists - creating unified diff' % filename)
232                 old_data = open(filename).read()
233                 diff = ''.join(difflib.unified_diff(old_data.splitlines(1), data    .splitlines(1)))
234                 if len(diff) > 0:
235                     log.info('%s has changed - adding diff' % url)
236                     details += foutput('changed', url, diff, summary)
237                 else:
238                     log.info('%s has not changed' % url)
239             else:
240                 log.info('%s does not exist - url is considered "new"' % filenam    e)
241                 details += foutput('new', url, None, summary)
242             log.info('writing current content of %s to %s' % (url, filename))

243             open(filename, 'w').write(data)
244         except urllib2.HTTPError, error:
245             log.error('got HTTPError while loading url: %s' % error)
246             if display_errors:
247                 details += foutput('error', url, error, summary)
248         except urllib2.URLError, error:
249             log.error('got URLError while loading url: %s' % error)
250             if display_errors:
251                 details += foutput('error', url, error, summary)

 

# 接下来是连续两个except捕捉异常

244         except urllib2.HTTPError, error:

248         except urllib2.URLError, error:

 

# 最后判断条件并输出结果

257     if len(summary) > 1:

268     if len(details) > 1:

 

--OVER,urlwatch比较简单,尽管我初学但还是看懂了,继续学习

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值