##// END OF EJS Templates
Changed sync processor output a bit
neko259 -
r2121:b378f45d default
parent child Browse files
Show More
@@ -1,135 +1,137 b''
1 import re
1 import re
2 import logging
2 import logging
3 import xml.etree.ElementTree as ET
3 import xml.etree.ElementTree as ET
4
4
5 import httplib2
5 import httplib2
6 from django.core.management import BaseCommand
6 from django.core.management import BaseCommand
7 from django.utils.dateparse import parse_datetime
7 from django.utils.dateparse import parse_datetime
8
8
9 from boards.models import GlobalId, KeyPair
9 from boards.models import GlobalId, KeyPair
10 from boards.models.post.sync import SyncManager, TAG_ID, TAG_UPDATE_TIME
10 from boards.models.post.sync import SyncManager, TAG_ID, TAG_UPDATE_TIME
11
11
12 __author__ = 'neko259'
12 __author__ = 'neko259'
13
13
14
14
15 REGEX_GLOBAL_ID = re.compile(r'(\w+)::([\w\+/]+)::(\d+)')
15 REGEX_GLOBAL_ID = re.compile(r'(\w+)::([\w\+/]+)::(\d+)')
16
16
17
17
18 class Command(BaseCommand):
18 class Command(BaseCommand):
19 help = 'Send a sync or get request to the server.'
19 help = 'Send a sync or get request to the server.'
20
20
21 def add_arguments(self, parser):
21 def add_arguments(self, parser):
22 parser.add_argument('url', type=str, help='Server root url')
22 parser.add_argument('url', type=str, help='Server root url')
23 parser.add_argument('--global-id', type=str, default='',
23 parser.add_argument('--global-id', type=str, default='',
24 help='Post global ID')
24 help='Post global ID')
25 parser.add_argument('--split-query', type=int, default=1,
25 parser.add_argument('--split-query', type=int, default=1,
26 help='Split GET query into separate by the given'
26 help='Split GET query into separate by the given'
27 ' number of posts in one')
27 ' number of posts in one')
28 parser.add_argument('--thread', type=int,
28 parser.add_argument('--thread', type=int,
29 help='Get posts of one specific thread')
29 help='Get posts of one specific thread')
30 parser.add_argument('--tags', type=str,
30 parser.add_argument('--tags', type=str,
31 help='Get posts of the tags, comma-separated')
31 help='Get posts of the tags, comma-separated')
32 parser.add_argument('--time-from', type=str,
32 parser.add_argument('--time-from', type=str,
33 help='Get posts from the given timestamp')
33 help='Get posts from the given timestamp')
34
34
35 def handle(self, *args, **options):
35 def handle(self, *args, **options):
36 logger = logging.getLogger('boards.sync')
36 logger = logging.getLogger('boards.sync')
37
37
38 url = options.get('url')
38 url = options.get('url')
39
39
40 list_url = url + 'api/sync/list/'
40 list_url = url + 'api/sync/list/'
41 get_url = url + 'api/sync/get/'
41 get_url = url + 'api/sync/get/'
42 file_url = url[:-1]
42 file_url = url[:-1]
43
43
44 global_id_str = options.get('global_id')
44 global_id_str = options.get('global_id')
45 if global_id_str:
45 if global_id_str:
46 match = REGEX_GLOBAL_ID.match(global_id_str)
46 match = REGEX_GLOBAL_ID.match(global_id_str)
47 if match:
47 if match:
48 key_type = match.group(1)
48 key_type = match.group(1)
49 key = match.group(2)
49 key = match.group(2)
50 local_id = match.group(3)
50 local_id = match.group(3)
51
51
52 global_id = GlobalId(key_type=key_type, key=key,
52 global_id = GlobalId(key_type=key_type, key=key,
53 local_id=local_id)
53 local_id=local_id)
54
54
55 xml = SyncManager.generate_request_get([global_id])
55 xml = SyncManager.generate_request_get([global_id])
56 h = httplib2.Http()
56 h = httplib2.Http()
57 response, content = h.request(get_url, method="POST", body=xml)
57 response, content = h.request(get_url, method="POST", body=xml)
58
58
59 SyncManager.parse_response_get(content, file_url)
59 SyncManager.parse_response_get(content, file_url)
60 else:
60 else:
61 raise Exception('Invalid global ID')
61 raise Exception('Invalid global ID')
62 else:
62 else:
63 logger.info('Running LIST request...')
63 logger.info('Running LIST request...')
64 h = httplib2.Http()
64 h = httplib2.Http()
65
65
66 tags = []
66 tags = []
67 tags_str = options.get('tags')
67 tags_str = options.get('tags')
68 if tags_str:
68 if tags_str:
69 tags = tags_str.split(',')
69 tags = tags_str.split(',')
70
70
71 timestamp_str = options.get('time_from')
71 timestamp_str = options.get('time_from')
72 timestamp = None
72 timestamp = None
73 if timestamp_str:
73 if timestamp_str:
74 timestamp = parse_datetime(timestamp_str)
74 timestamp = parse_datetime(timestamp_str)
75
75
76 xml = SyncManager.generate_request_list(
76 xml = SyncManager.generate_request_list(
77 opening_post=options.get('thread'), tags=tags,
77 opening_post=options.get('thread'), tags=tags,
78 timestamp_from=timestamp).encode()
78 timestamp_from=timestamp).encode()
79 response, content = h.request(list_url, method="POST", body=xml)
79 response, content = h.request(list_url, method="POST", body=xml)
80 if response.status != 200:
80 if response.status != 200:
81 raise Exception('Server returned error {}'.format(response.status))
81 raise Exception('Server returned error {}'.format(response.status))
82
82
83 logger.info('Processing response...')
83 logger.info('Processing response...')
84
84
85 root = ET.fromstring(content)
85 root = ET.fromstring(content)
86 status = root.findall('status')[0].text
86 status = root.findall('status')[0].text
87 if status == 'success':
87 if status == 'success':
88 ids_to_sync = list()
88 ids_to_sync = list()
89
89
90 models = root.findall('models')[0]
90 models = root.findall('models')[0]
91 for model in models:
91 for model in models:
92 tag_id = model.find(TAG_ID)
92 self.add_to_sync_list(ids_to_sync, logger, model)
93 global_id, exists = GlobalId.from_xml_element(tag_id)
94
95 from_this_board = self._is_from_this_board(global_id)
96
97 if from_this_board:
98 # If the post originates from this board, no need to process
99 # it again, nobody else could modify it
100 logger.debug('* Processed (-) post {}'.format(global_id))
101 else:
102 tag_update_time = model.find(TAG_UPDATE_TIME)
103 if tag_update_time:
104 update_time = tag_update_time.text
105 else:
106 update_time = None
107 if not exists or update_time is None or global_id.post.last_edit_time < parse_datetime(update_time):
108 logger.debug('Processed (+) post {}'.format(global_id))
109 ids_to_sync.append(global_id)
110 else:
111 logger.debug('* Processed (-) post {}'.format(global_id))
112 logger.info('Starting sync...')
93 logger.info('Starting sync...')
113
94
114 if len(ids_to_sync) > 0:
95 if len(ids_to_sync) > 0:
115 limit = options.get('split_query', len(ids_to_sync))
96 limit = options.get('split_query', len(ids_to_sync))
116 for offset in range(0, len(ids_to_sync), limit):
97 for offset in range(0, len(ids_to_sync), limit):
117 xml = SyncManager.generate_request_get(ids_to_sync[offset:offset + limit])
98 xml = SyncManager.generate_request_get(ids_to_sync[offset:offset + limit])
118 h = httplib2.Http()
99 h = httplib2.Http()
119 logger.info('Running GET request...')
100 logger.info('Running GET request...')
120 response, content = h.request(get_url, method="POST", body=xml)
101 response, content = h.request(get_url, method="POST", body=xml)
121 logger.info('Processing response...')
102 logger.info('Processing response...')
122
103
123 SyncManager.parse_response_get(content, file_url)
104 SyncManager.parse_response_get(content, file_url)
124
105
125 logger.info('Sync completed successfully')
106 logger.info('Sync completed successfully')
126 else:
107 else:
127 logger.info('Nothing to get, everything synced')
108 logger.info('Nothing to get, everything synced')
128 else:
109 else:
129 raise Exception('Invalid response status')
110 raise Exception('Invalid response status')
130
111
112 def add_to_sync_list(self, ids_to_sync, logger, model):
113 tag_id = model.find(TAG_ID)
114 global_id, exists = GlobalId.from_xml_element(tag_id)
115 from_this_board = self._is_from_this_board(global_id)
116 if from_this_board:
117 # If the post originates from this board, no need to process
118 # it again, nobody else could modify it
119 logger.debug('NO SYNC Processed post {}'.format(global_id))
120 else:
121 tag_update_time = model.find(TAG_UPDATE_TIME)
122 if tag_update_time:
123 update_time = tag_update_time.text
124 else:
125 update_time = None
126 if not exists or update_time is None or global_id.post.last_edit_time < parse_datetime(
127 update_time):
128 logger.debug('SYNC Processed post {}'.format(global_id))
129 ids_to_sync.append(global_id)
130 else:
131 logger.debug('NO SYNC Processed post {}'.format(global_id))
132
131 def _is_from_this_board(self, global_id):
133 def _is_from_this_board(self, global_id):
132 from_this_board = KeyPair.objects.filter(
134 from_this_board = KeyPair.objects.filter(
133 key_type=global_id.key_type,
135 key_type=global_id.key_type,
134 public_key=global_id.key).exists()
136 public_key=global_id.key).exists()
135 return from_this_board
137 return from_this_board
General Comments 0
You need to be logged in to leave comments. Login now