Advertisement
Guest User

Untitled

a guest
Oct 10th, 2016
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.29 KB | None | 0 0
  1. # coding=utf-8
  2.  
  3. """
  4. Алгоритм:
  5.  
  6. - Добавляем колонку "_id" (nullable) в kposts
  7. - Добавляем колонку "_parentid" (nullable) в kposts
  8. Смысл этих операций в том, чтобы запомнить прошлые значения постов
  9. Заполняем колонки значениями _id=id, _parentid=parentid
  10.  
  11. - Меняем boardid 6 на boardid 4
  12. - Обнуляем id у всех постов с boardid = 4
  13. Номера всем постам мы поставим заново, это проще чем рассчитывать номера для слияния
  14.  
  15. - Проставляем новые номера постам с boardid = 4, алгоритм при этом такой:
  16. - Сортируем все посты по возрастанию timestamp и проставляем каждому id начиная с 1
  17. - Проходимся по каждому посту еще раз, меняем parentid на новый id поста (матчим по _parentid),
  18. если в посте есть >>ссылка, меняем ее на новую ссылку (матчим по _id)
  19.  
  20. """
  21.  
  22. import psycopg2
  23. from bs4 import BeautifulSoup
  24.  
  25.  
  26. DB_NAME = 'zadrawch_wip'
  27. DB_USER = 'zadrawch'
  28. DB_HOST = 'localhost'
  29. DB_PASSWORD = '12345'
  30.  
  31. SRC_BOARD_ID = 6 # С какой доски переносим посты
  32. DST_BOARD_ID = 4 # В какую доску переносим посты
  33.  
  34. SRC_BOARD_NAME = '2dwip'
  35. DST_BOARD_NAME = '2d'
  36.  
  37. MERGE_SQL = '''
  38.  
  39. ALTER TABLE kposts DROP CONSTRAINT kposts_pkey;
  40.  
  41. ALTER TABLE kposts ADD COLUMN "_id" integer;
  42. ALTER TABLE kposts ADD COLUMN "_parentid" integer;
  43. ALTER TABLE kposts ADD COLUMN "_boardid" integer;
  44.  
  45. UPDATE kposts SET _id=id, _parentid=parentid, _boardid=boardid WHERE boardid IN (%(src_board_id)s, %(dst_board_id)s);
  46.  
  47. UPDATE kposts SET boardid = %(dst_board_id)s WHERE boardid = %(src_board_id)s;
  48.  
  49. WITH upd as (
  50. SELECT row_number() OVER (ORDER BY timestamp) as new_id,
  51. _boardid,
  52. id as old_id
  53. FROM kposts
  54. WHERE boardid = %(dst_board_id)s
  55. ORDER BY timestamp ASC
  56. )
  57. UPDATE kposts a
  58. SET
  59. id = b.new_id
  60. FROM upd b
  61. WHERE
  62. a.id = b.old_id AND a._boardid = b._boardid;
  63.  
  64. ALTER TABLE kposts ADD PRIMARY KEY (boardid, id);
  65.  
  66. UPDATE kposts a
  67. SET parentid = CASE
  68. WHEN a._parentid = 0 THEN 0
  69. ELSE b.id
  70. END
  71. FROM kposts b
  72. WHERE b._id = a._parentid AND a._boardid = b._boardid;
  73. '''
  74.  
  75. CLEANUP_SQL = '''
  76. ALTER TABLE kposts DROP COLUMN _boardid;
  77. ALTER TABLE kposts DROP COLUMN _id;
  78. ALTER TABLE kposts DROP COLUMN _parentid;
  79. '''
  80.  
  81.  
  82. def fix_refs(cur, row):
  83. """
  84. <a href=\"/2dwip/res/88.html#93\" onclick=\"return highlight(\'93\', true);\" class=\"ref|2dwip|88|93\">>>93</a>\r
  85. <br />
  86. пока не очень получается, попытался изобразить кровь\r
  87. <br />
  88. <a href=\"/2dwip/res/88.html#94\" onclick=\"return highlight(\'94\', true);\" class=\"ref|2dwip|88|94\">>>94</a>
  89. <a href=\"/2dwip/res/88.html#95\" onclick=\"return highlight(\'95\', true);\" class=\"ref|2dwip|88|95\">>>95</a>\r
  90. <br />
  91. хочется дать карандашу отдохнуть анончики
  92. <br />
  93. """
  94. post_id, boardid, message = row
  95. message = message.replace('\r', '')
  96.  
  97. soup = BeautifulSoup(message)
  98.  
  99. for ref in soup.findAll('a'):
  100. try:
  101. ref_class = ref['class'][0]
  102. except KeyError:
  103. continue
  104. ref_href = ref['href']
  105.  
  106. old_thread_id = int(ref_href.split('/')[-1].split('.')[0])
  107. cur.execute("SELECT id FROM kposts WHERE _id = %(old_id)s AND _boardid = %(old_boardid)s", {
  108. 'old_id': old_thread_id,
  109. 'old_boardid': SRC_BOARD_ID if SRC_BOARD_NAME in ref_class else DST_BOARD_ID,
  110. })
  111. try:
  112. new_thread_id = cur.fetchone()[0]
  113. except TypeError:
  114. continue
  115.  
  116. old_post_id = int(u''.join([s for s in ref_href.split('/')[-1].split('#')[-1] if s.isdigit()]))
  117. cur.execute("SELECT id FROM kposts WHERE _id = %(old_id)s AND _boardid = %(old_boardid)s", {
  118. 'old_id': old_post_id,
  119. 'old_boardid': SRC_BOARD_ID if SRC_BOARD_NAME in ref_class else DST_BOARD_ID,
  120. })
  121. try:
  122. new_post_id = cur.fetchone()[0]
  123. except TypeError:
  124. continue
  125.  
  126. new_href = '/{board}/res/{thread_id}.html#{post_id}'.format(
  127. board=DST_BOARD_NAME,
  128. thread_id=new_thread_id,
  129. post_id=new_post_id,
  130. )
  131. ref['href'] = new_href
  132.  
  133. ref['onclick'] = "return highlight('{new_post_id}, true')".format(new_post_id=new_post_id)
  134.  
  135. fixed_class = "ref|{board}|{thread_id}|{post_id}".format(
  136. board=DST_BOARD_NAME,
  137. thread_id=new_thread_id,
  138. post_id=new_post_id,
  139. )
  140.  
  141. ref['class'] = [fixed_class]
  142.  
  143. del ref['highlight']
  144. del ref['true']
  145.  
  146. ref.string = '>>{new_post_id}'.format(new_post_id=new_post_id)
  147.  
  148. fixed_message = str(soup)
  149. fixed_message = fixed_message.replace('<html><body>', '').replace('</body></html>', '')
  150.  
  151. cur.execute('UPDATE kposts SET message = %(fixed_message)s WHERE id = %(post_id)s', {
  152. 'fixed_message': fixed_message,
  153. 'post_id': post_id,
  154. })
  155.  
  156.  
  157. def merge_boards():
  158. with psycopg2.connect(
  159. dbname=DB_NAME,
  160. user=DB_USER,
  161. host=DB_HOST,
  162. password=DB_PASSWORD,
  163. ) as conn:
  164. with conn.cursor() as cur:
  165.  
  166. print 'Merging boards...'
  167.  
  168. cur.execute(MERGE_SQL, {
  169. 'src_board_id': SRC_BOARD_ID,
  170. 'dst_board_id': DST_BOARD_ID,
  171. })
  172.  
  173. print 'Updating refs...'
  174.  
  175. # Selecting all '>>1222'-like refs
  176. cur.execute("SELECT id, boardid, \"message\" FROM kposts WHERE boardid = %(dst_board_id)s AND \"message\" like '%%>>%%'", {
  177. 'dst_board_id': DST_BOARD_ID,
  178. })
  179.  
  180. rows = cur.fetchall()
  181. for i, row in enumerate(rows):
  182. if i % 10 == 0:
  183. print 'Updated {} posts'.format(i)
  184. fix_refs(cur, row)
  185.  
  186. print 'Cleaning...'
  187. cur.execute(CLEANUP_SQL)
  188.  
  189. if __name__ == '__main__':
  190. merge_boards()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement