joe 4 years ago
parent
commit
b2cafa72b5
1 changed files with 105 additions and 45 deletions
  1. 105 45
      pdetails.py

+ 105 - 45
pdetails.py

@@ -1,14 +1,16 @@
 
 import os
 import sys
+import requests
 from os import path
+from posixpath import join as posixjoin
 from urllib import request
 from qiniu import Auth, put_file, etag
 
 """
 # 功能说明
 1) 使用大仙批量下载产品图片后,需要手动修改主图,详情图,主要删除不合适的图片,保留下来的作为最终要呈现的产品资料
-这些经过处理后的图片位于硬盘中某个目录下,这个目录就是本脚本要处理的根目录.
+这些经过处理后的图片位于硬盘中某个目录下,这个目录就是本脚本要处理的根目录.
 2) 本脚本主要解析处理目录中所有的产品图片,解析,上传,逻辑如下:
 a. 提取产品名称
 b. 上传主图到七牛
@@ -16,7 +18,8 @@ c. 上传详情图到七牛
 d. 生成详情页内容html格式文本
 e. 提取产品价格
 f. 把每个产品的以上信息输出到产品对应的目录
-3) 脚本任务就完成了. 之后需要到后台处理.添加图片必须作为远程图片添加. 需要稍微编辑产品其他信息
+g. 把图片的远程地址结合产品信息上传到后台服务器进行管理
+3) 脚本任务就完成了. 之后需要到后台处理. 需要编辑产品其他信息
 
 # 脚本使用
 cd /path/to/pdetails.py
@@ -24,8 +27,9 @@ python pdetails.py <root_dir>
 
 """
 
-_VERSION_ = '0.0.1'
+_VERSION_ = '0.1.2'
 _DATE_ = '2021-01-04'
+_AUTHOR_ = 'wenstudio@asia.com'
 
 # 七牛配置
 KEY_ACCESS = 'SneSBtnWLdStBhCx0O_QogNkXoRlKNOiv1--XMBB'
@@ -35,13 +39,20 @@ KEY_SECRET = 'GXMg-ENcp2UKYQWdeaf43tk_06NnMoA4OVFxdkYw'
 BUCKET_NAME = 'twong'
 BUCKET_DOMAIN = 'http://twongpic.shotshock.shop'
 
+TWONG = 'http://twong.shotshock.shop'
+
 # 产品字典, 从 csv 文件中解析, 用于查找价格
 DICT_PROD = {}
 
+print('pdetails-v{}. 美天旺项目内部工具\n'.format(_VERSION_))
 
 def remote_img_exists(url):
     """
     检查远程文件是否已存在
+
+    @url: remote image url
+
+    @return: boolean.
     """
     try:
         request.urlopen(url)
@@ -53,7 +64,11 @@ def remote_img_exists(url):
 def parse_prod_root_name(name):
     """
     ROOT_DIR 下是一个个产品的资料目录, 解析这个目录名, 得到开头的数字串,作为上传到七牛后该产品的子路径
-    返回 数字串,产品名 或 False, False
+
+    @name: path name
+
+    @return str, str.
+        数字串,产品名 或 False, False
     """
     parts = name.split('_')
     if len(parts) != 3:
@@ -63,49 +78,71 @@ def parse_prod_root_name(name):
 
 def parse_csv(csv):
     """
-    解析 csv 文件
-    返回名称-价格字典
+    @csv: csv file
+
+    @return: dict
+        the most important columns in the csv file.
     """
     d = {}
     with open(csv, 'rt', encoding='GBK') as h:
+        # version line
+        version_line = h.readline()
+        parts = version_line.split(' ')
+        if len(parts) != 2 or parts[1].lower().strip() != '1.00':
+            print('ERROR: unsupported csv file version. please update this software.')
+            exit(0)
+        # english headers
+        eng_headers = h.readline().split(',')
+        cn_headers = h.readline().split(',')
+        # products
         while True:
-            line = h.readline()
-            if not line:
+            values = h.readline()
+            if not values:
                 break
-            parts = line.split(',')
-            if len(parts) != 59:
-                continue
-            key = parts[0][1:-1]
-            d[key] = parts[7]
+            values = values.split(',')
+            key = values[0].strip(' "')
+            d[key] = {}
+            # extract some columes
+            for x in [7,9,10,11]:
+                d[key][cn_headers[x]] = values[x].strip(' "')
     return d
 
 
 def upload(code, img):
     """
-    code: parse_prod_root_name 返回的产品代码
     上传文件到七牛
+
+    @code: parse_prod_root_name 返回的产品代码
+    @img: local image file to be uploaded
+
+    @return str/False. url of image uploaded or False
     """
     name = path.basename(img)
     a = Auth(access_key=KEY_ACCESS, secret_key=KEY_SECRET)
     t = a.upload_token(BUCKET_NAME,)
-    key = path.join(code, name)
+    key = posixjoin(code, name)
     ret, res = put_file(t, key, img)
     if res.status_code == 200 and not res.exception:
-        return path.join(BUCKET_DOMAIN, key)
+        return posixjoin(BUCKET_DOMAIN, key)
     return False
 
 
 def gen_details(imgs):
     """
-    根据图片 url 生成详情页内容,返回
+    根据图片 url 生成详情页内容
+
+    @imgs: url of images uploaded
+    
+    @return: str, product details.
     """
     content = ''
     for img in imgs:
-        content += '<p>\n<img src="' + img + '">\n<p>\n'
+        content += '<p>\n<img src="' + img + '" />\n</p>\n'
     return content
 
 
 def main(root):
+    # find and parse csv file
     global DICT_PROD
     all = os.listdir(root)
     for each in all:
@@ -115,7 +152,8 @@ def main(root):
             if ext == '.csv':
                 DICT_PROD = parse_csv(full)
                 print('INFO: csv loaded.')
-
+	
+    products = []
     for each in all:
         full = path.join(root, each)
         if path.isdir(full):
@@ -123,39 +161,66 @@ def main(root):
             if not code:
                 print('WARNING: skipped ', full)
                 continue
+            product = {}
             # 处理主图
-            urls = _upload_main_images(code, path.join(full, '主图'))
+            main_imgs = _upload_images(code, path.join(full, '主图'), 6)
+            # 处理属性图
+            attr_imgs = _upload_images(code, path.join(full, '属性图'))
             # 处理详情图
-            contents = _upload_details_images(code, path.join(full, '细节图'))
+            details_imgs = _upload_images(code, path.join(full, '细节图'))
+            details_text = gen_details(details_imgs)
             # 保存文件
-            _save_prod(path.join(full, code), name, urls, contents)
+            _save_prod(path.join(root, '{}_{}.txt'.format(code, name)), name, main_imgs, details_text)
             print('INFO: {} processed OK.'.format(name))
+            product['name'] = name
+            product['images'] = [main_imgs or [], attr_imgs or [], details_imgs or []]
+            products.append(product)
+
+    # upload to server
+    if not _upload_remote_images_to_twong(products):
+        print('ERROR: upload to manager failed.')
 
 
 def _save_prod(local, name, urls, details):
     """
-    save single product info into specified file
+    Save single product info into specified file
+
+    @local: local file to be saved
+    @name: product name
+    @urls: main pictures url
+    @details: details content
+
+    @return: None
     """
     with open(local, 'wt', encoding='utf8') as h:
         price = DICT_PROD[name] if name in DICT_PROD else 0.0
-        h.write('name:{}\n'.format(name))
-        h.write('price: {}\nimages:\n'.format(price))
+        h.write('产品名:{}\n'.format(name))
+        if DICT_PROD.get(name):
+            for k, v in DICT_PROD.get(name).items():
+                h.write('{}: {}\n'.format(k, v))
+        h.write('\n主图:\n')
         for url in urls:
             h.write(url)
             h.write('\n')
-        h.write('details:\n')
+        h.write('\n详情html:\n')
         h.write(details)
 
 
-def _upload_main_images(code, dir):
+def _upload_images(code, dir, max=0):
     """
-    上传主图
-    返回 url 列表
+    Upload images to qiniu OSS
+
+    @code: code of product, this code will be upload as the parent directory of all pictures
+    @dir: dir of pictures to be uploaded.
+    @max: max num picutures to uploaded
+    
+    @return: list, urls of all pictures uploaded.
     """
     urls = []
     images = os.listdir(dir)
     images.sort()
-    images = images[:6]
+    if max:
+        images = images[:max]
     for img in images:
         full = path.join(dir, img)
         url = upload(code, full)
@@ -166,28 +231,23 @@ def _upload_main_images(code, dir):
     return urls
 
 
-def _upload_details_images(code, dir):
+def _upload_remote_images_to_twong(products):
     """
-    上传详情图
-    返回 详情页 html 内容
+    上传至七牛的图片 url 再次上传到后台进行管理
+    @products: dict, 可转化为 json 的参数
+    
+    @return boolean
     """
-    urls = []
-    images = os.listdir(dir)
-    images.sort()
-    for img in images:
-        full = path.join(dir, img)
-        url = upload(code, full)
-        if not url:
-            print('ERROR: upload failed ', full)
-            continue
-        urls.append(url)
-    return gen_details(urls)
+    end_point = '{}/admin/PublicAdmin/reg_images?k={}'.format(TWONG, 'twong')
+    r = requests.post(url=end_point, json={'products':products})
+    print(r.text)
+    return r.status_code == 200
 
 
 # testing
 if __name__ == '__main__':
     if len(sys.argv) < 2:
         print('ERROR: root dir of images not given. quit')
-        exit(0)
+        sys.exit(0)
     main(sys.argv[-1])
     print('Done.')