OSDN Git Service

add wp_imgswap2.py for new OSDN Magazine
[otptools/otptools.git] / StoryList2 / fetch_storylist.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 import os
5 import sys
6 import getpass
7 import otptools2
8 import time
9 import datetime
10 import sqlite3
11 import re
12
13
14 usage = sys.argv[0] + """ start end <output_file>
15 """
16
17 DATABASE = "./story.db"
18
19 try:
20     start = sys.argv[1]
21     end = sys.argv[2]
22 except IndexError:
23     sys.exit(usage)
24
25 if (not start.isdigit()) or (not start.isdigit()):
26     sys.exit(usage)
27
28 def login(otp, uname=""):
29     if uname == "":
30         try:
31             uname = raw_input("user: ")
32         except KeyboardInterrupt:
33             sys.exit("\nabort.")
34         try:
35             passwd = getpass.getpass("login password:")
36         except KeyboardInterrupt:
37             sys.exit("\nabort.")
38         if not otp.login(uname, passwd):
39             sys.exit("login error!")
40     otp.save_cookie()
41
42 def prepare_database():
43     if os.path.exists(DATABASE):
44         return
45     con = sqlite3.connect(DATABASE)
46     cur = con.cursor()
47
48     cmd = """create table stories (
49   sid text unique,
50   title text default "",
51   author text default "",
52   section text default "",
53   topic text default "",
54   view int default 0,
55   comments int default 0,
56   date real
57 )"""
58     cur.execute(cmd)
59
60     cmd = """create table topics (
61   sid text,
62   topic text
63 )"""
64     cur.execute(cmd)
65
66     con.commit()
67     cur.close()
68     con.close()
69
70
71 def str2date(str):
72     "01/01 01:01 -> datetime"
73     m = re.search(r"([0-9][0-9])/([0-9][0-9]) ([0-9][0-9]):([0-9][0-9])", str)
74     if m:
75         dateint = [int(m.group(x)) for x in xrange(1,5)]
76         year = datetime.datetime.today().year
77         month = datetime.datetime.today().month
78         if month < dateint[0]:
79             year -= 1
80
81         dt = datetime.datetime(year, dateint[0], dateint[1], dateint[2], dateint[3])
82         return dt
83     else:
84         return None
85
86 def query_sid(sid):
87     con = sqlite3.connect(DATABASE)
88     cur = con.cursor()
89     cmd = """select sid from stories where ?"""
90     cur.execute(cmd, (sid,))
91     if len(cur) != 0:
92         return 
93     
94
95 def insert_story_info(otp, story_info):
96     con = sqlite3.connect(DATABASE)
97     cur = con.cursor()
98
99     si = {}
100     rex_sid = re.compile(r"/magazine.sourceforge.jp/article.pl\?sid=([0-9/]*)$")
101
102     m = rex_sid.search(story_info["url"])
103     if m:
104         sid = m.group(1)
105     else:
106        return False 
107     si["sid"] = sid
108     si["title"] = story_info["title"]
109     si["author"] = story_info["author"]
110
111     dt = str2date(story_info["datetime"])
112     si["date"] = time.mktime(dt.timetuple())
113     try:
114         cur.execute("""insert into stories ( sid, title, author, date )
115                                     values ( :sid, :title, :author, :date )""",
116                     si)
117     except sqlite3.IntegrityError:
118         cur.execute("""update stories set title = :title,
119                                           author = :author,
120                                           date = :date
121                                       where sid=:sid""",
122                     si)
123
124     tags = otp.get_tags("/magazine.sourceforge.jp/article.pl?sid=" + sid)
125     title = otp.get_title("/magazine.sourceforge.jp/article.pl?sid=" + sid)
126
127     sys.stderr.write(".")
128     sys.stderr.flush()
129
130     cur.execute("""delete from topics where sid=?""", (sid,))
131
132     for tag in tags:
133         tag = tag.decode("utf-8")
134         cur.execute("""insert into topics ( sid, topic )
135                                    values ( :sid, :topic )""",
136                     dict(sid=sid, topic=tag))
137
138     if title:
139         title = title.decode("utf-8").replace("Open Tech Press |", "").strip()
140         cur.execute("""update stories set title = :title
141                                       where sid = :sid""",
142                     dict(sid=sid, title=title))
143     con.commit()
144     cur.close()
145     con.close()
146
147 # main proc.
148 def main(start, end):
149     otp = otptools2.otptools("./cookies.txt")
150     try:
151         otp.load_cookie()
152     except IOError:
153         sys.stderr.write("cannot use cookie file. create.\n")
154
155     if otp.get_cookie() == "":
156         login(otp)
157         otp.save_cookie()
158
159     story_infos = {}
160     start_index = int(start)
161     end_index = int(end)
162
163     prepare_database()
164     sys.stderr.write( "retrieving lists..." )
165
166     for index in range(start_index, end_index, 40):
167         html = otp.get_list(index)
168         story_infos = otp.parse_list(html, story_infos)
169
170         for key in story_infos:
171             insert_story_info(otp, story_infos[key])
172             
173     sys.stderr.write( "done.\n" )
174 #### end of functions
175
176 # do main proc.
177 main(start, end)