client.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # filename: client.py
  4. '''
  5. Client module for Fastdfs 3.08
  6. author: scott yuan scottzer8@gmail.com
  7. date: 2012-06-21
  8. '''
  9. import os, sys
  10. from fdfs_client.utils import *
  11. from fdfs_client.tracker_client import *
  12. from fdfs_client.storage_client import *
  13. from fdfs_client.exceptions import *
  14. def get_tracker_conf(conf_path = 'client.conf'):
  15. cf = Fdfs_ConfigParser()
  16. tracker = {}
  17. try:
  18. cf.read(conf_path)
  19. timeout = cf.getint('__config__', 'connect_timeout')
  20. tracker_list = cf.get('__config__', 'tracker_server')
  21. if isinstance(tracker_list, str):
  22. tracker_list = [tracker_list]
  23. tracker_ip_list = []
  24. for tr in tracker_list:
  25. tracker_ip, tracker_port = tr.split(':')
  26. tracker_ip_list.append(tracker_ip)
  27. tracker['host_tuple'] = tuple(tracker_ip_list)
  28. tracker['port'] = int(tracker_port)
  29. tracker['timeout'] = timeout
  30. tracker['name'] = 'Tracker Pool'
  31. except:
  32. raise
  33. return tracker
  34. class Fdfs_client(object):
  35. '''
  36. Class Fdfs_client implemented Fastdfs client protol ver 3.08.
  37. It's useful upload, download, delete file to or from fdfs server, etc. It's uses
  38. connection pool to manage connection to server.
  39. '''
  40. def __init__(self, conf_path = '/etc/fdfs/client.conf', \
  41. poolclass =ConnectionPool):
  42. self.trackers = get_tracker_conf(conf_path)
  43. self.tracker_pool = poolclass(**self.trackers)
  44. self.timeout = self.trackers['timeout']
  45. return None
  46. def __del__(self):
  47. try:
  48. self.pool.destroy()
  49. self.pool = None
  50. except:
  51. pass
  52. def upload_by_filename(self, filename, meta_dict = None):
  53. '''
  54. Upload a file to Storage server.
  55. arguments:
  56. @filename: string, name of file that will be uploaded
  57. @meta_dict: dictionary e.g.:{
  58. 'ext_name' : 'jpg',
  59. 'file_size' : '10240B',
  60. 'width' : '160px',
  61. 'hight' : '80px'
  62. } meta_dict can be null
  63. @return dict {
  64. 'Group name' : group_name,
  65. 'Remote file_id' : remote_file_id,
  66. 'Status' : 'Upload successed.',
  67. 'Local file name' : local_file_name,
  68. 'Uploaded size' : upload_size,
  69. 'Storage IP' : storage_ip
  70. } if success else None
  71. '''
  72. isfile, errmsg = fdfs_check_file(filename)
  73. if not isfile:
  74. raise DataError(errmsg + '(uploading)')
  75. tc = Tracker_client(self.tracker_pool)
  76. store_serv = tc.tracker_query_storage_stor_without_group()
  77. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  78. return store.storage_upload_by_filename(tc, store_serv, filename, meta_dict)
  79. def upload_by_file(self, filename, meta_dict = None):
  80. isfile, errmsg = fdfs_check_file(filename)
  81. if not isfile:
  82. raise DataError(errmsg + '(uploading)')
  83. tc = Tracker_client(self.tracker_pool)
  84. store_serv = tc.tracker_query_storage_stor_without_group()
  85. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  86. return store.storage_upload_by_file(tc, store_serv, filename, meta_dict)
  87. def upload_by_buffer(self, filebuffer, file_ext_name = None, meta_dict = None):
  88. '''
  89. Upload a buffer to Storage server.
  90. arguments:
  91. @filebuffer: string, buffer
  92. @file_ext_name: string, file extend name
  93. @meta_dict: dictionary e.g.:{
  94. 'ext_name' : 'jpg',
  95. 'file_size' : '10240B',
  96. 'width' : '160px',
  97. 'hight' : '80px'
  98. }
  99. @return dict {
  100. 'Group name' : group_name,
  101. 'Remote file_id' : remote_file_id,
  102. 'Status' : 'Upload successed.',
  103. 'Local file name' : '',
  104. 'Uploaded size' : upload_size,
  105. 'Storage IP' : storage_ip
  106. } if success else None
  107. '''
  108. if not filebuffer:
  109. raise DataError('[-] Error: argument filebuffer can not be null.')
  110. tc = Tracker_client(self.tracker_pool)
  111. store_serv = tc.tracker_query_storage_stor_without_group()
  112. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  113. return store.storage_upload_by_buffer(tc, store_serv, filebuffer, \
  114. file_ext_name, meta_dict)
  115. def upload_slave_by_filename(self, filename, remote_file_id, prefix_name, \
  116. meta_dict = None):
  117. '''
  118. Upload slave file to Storage server.
  119. arguments:
  120. @filename: string, local file name
  121. @remote_file_id: string, remote file id
  122. @prefix_name: string
  123. @meta_dict: dictionary e.g.:{
  124. 'ext_name' : 'jpg',
  125. 'file_size' : '10240B',
  126. 'width' : '160px',
  127. 'hight' : '80px'
  128. }
  129. @return dictionary {
  130. 'Status' : 'Upload slave successed.',
  131. 'Local file name' : local_filename,
  132. 'Uploaded size' : upload_size,
  133. 'Remote file id' : remote_file_id,
  134. 'Storage IP' : storage_ip
  135. }
  136. '''
  137. isfile, errmsg = fdfs_check_file(filename)
  138. if not isfile:
  139. raise DataError(errmsg + '(uploading slave)')
  140. tmp = split_remote_fileid(remote_file_id)
  141. if not tmp:
  142. raise DataError('[-] Error: remote_file_id is invalid.(uploading slave)')
  143. if not prefix_name:
  144. raise DataError('[-] Error: prefix_name can not be null.')
  145. group_name, remote_filename = tmp
  146. tc = Tracker_client(self.tracker_pool)
  147. store_serv = tc.tracker_query_storage_stor_with_group(group_name)
  148. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  149. try:
  150. ret_dict = store.storage_upload_slave_by_filename(tc, store_serv, filename, \
  151. prefix_name, remote_filename, \
  152. meta_dict = None)
  153. except:
  154. raise
  155. ret_dict['Status'] = 'Upload slave file successed.'
  156. return ret_dict
  157. def upload_slave_by_file(self, filename, remote_file_id, prefix_name, \
  158. meta_dict = None):
  159. '''
  160. Upload slave file to Storage server.
  161. arguments:
  162. @filename: string, local file name
  163. @remote_file_id: string, remote file id
  164. @prefix_name: string
  165. @meta_dict: dictionary e.g.:{
  166. 'ext_name' : 'jpg',
  167. 'file_size' : '10240B',
  168. 'width' : '160px',
  169. 'hight' : '80px'
  170. }
  171. @return dictionary {
  172. 'Status' : 'Upload slave successed.',
  173. 'Local file name' : local_filename,
  174. 'Uploaded size' : upload_size,
  175. 'Remote file id' : remote_file_id,
  176. 'Storage IP' : storage_ip
  177. }
  178. '''
  179. isfile, errmsg = fdfs_check_file(filename)
  180. if not isfile:
  181. raise DataError(errmsg + '(uploading slave)')
  182. tmp = split_remote_fileid(remote_file_id)
  183. if not tmp:
  184. raise DataError('[-] Error: remote_file_id is invalid.(uploading slave)')
  185. if not prefix_name:
  186. raise DataError('[-] Error: prefix_name can not be null.')
  187. group_name, remote_filename = tmp
  188. tc = Tracker_client(self.tracker_pool)
  189. store_serv = tc.tracker_query_storage_stor_with_group(group_name)
  190. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  191. try:
  192. ret_dict = store.storage_upload_slave_by_file(tc, store_serv, filename, \
  193. prefix_name, remote_filename, \
  194. meta_dict = None)
  195. except:
  196. raise
  197. ret_dict['Status'] = 'Upload slave file successed.'
  198. return ret_dict
  199. def upload_slave_by_buffer(self, filebuffer, remote_file_id, \
  200. meta_dict = None, file_ext_name = None):
  201. '''
  202. Upload slave file by buffer
  203. arguments:
  204. @filebuffer: string
  205. @remote_file_id: string
  206. @meta_dict: dictionary e.g.:{
  207. 'ext_name' : 'jpg',
  208. 'file_size' : '10240B',
  209. 'width' : '160px',
  210. 'hight' : '80px'
  211. }
  212. @return dictionary {
  213. 'Status' : 'Upload slave successed.',
  214. 'Local file name' : local_filename,
  215. 'Uploaded size' : upload_size,
  216. 'Remote file id' : remote_file_id,
  217. 'Storage IP' : storage_ip
  218. }
  219. '''
  220. if not filebuffer:
  221. raise DataError('[-] Error: argument filebuffer can not be null.')
  222. tmp = split_remote_fileid(remote_file_id)
  223. if not tmp:
  224. raise DataError('[-] Error: remote_file_id is invalid.(uploading slave)')
  225. group_name, remote_filename = tmp
  226. tc = Tracker_client(self.tracker_pool)
  227. store_serv = tc.tracker_query_storage_update(group_name, remote_filename)
  228. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  229. return store.storage_upload_slave_by_buffer(tc, store_serv, filebuffer, \
  230. remote_filename, meta_dict, \
  231. file_ext_name)
  232. def upload_appender_by_filename(self, local_filename, meta_dict = None):
  233. '''
  234. Upload an appender file by filename.
  235. arguments:
  236. @local_filename: string
  237. @meta_dict: dictionary e.g.:{
  238. 'ext_name' : 'jpg',
  239. 'file_size' : '10240B',
  240. 'width' : '160px',
  241. 'hight' : '80px'
  242. } Notice: it can be null
  243. @return dict {
  244. 'Group name' : group_name,
  245. 'Remote file_id' : remote_file_id,
  246. 'Status' : 'Upload successed.',
  247. 'Local file name' : '',
  248. 'Uploaded size' : upload_size,
  249. 'Storage IP' : storage_ip
  250. } if success else None
  251. '''
  252. isfile, errmsg = fdfs_check_file(local_filename)
  253. if not isfile:
  254. raise DataError(errmsg + '(uploading appender)')
  255. tc = Tracker_client(self.tracker_pool)
  256. store_serv = tc.tracker_query_storage_stor_without_group()
  257. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  258. return store.storage_upload_appender_by_filename(tc, store_serv, \
  259. local_filename, meta_dict)
  260. def upload_appender_by_file(self, local_filename, meta_dict = None):
  261. '''
  262. Upload an appender file by file.
  263. arguments:
  264. @local_filename: string
  265. @meta_dict: dictionary e.g.:{
  266. 'ext_name' : 'jpg',
  267. 'file_size' : '10240B',
  268. 'width' : '160px',
  269. 'hight' : '80px'
  270. } Notice: it can be null
  271. @return dict {
  272. 'Group name' : group_name,
  273. 'Remote file_id' : remote_file_id,
  274. 'Status' : 'Upload successed.',
  275. 'Local file name' : '',
  276. 'Uploaded size' : upload_size,
  277. 'Storage IP' : storage_ip
  278. } if success else None
  279. '''
  280. isfile, errmsg = fdfs_check_file(local_filename)
  281. if not isfile:
  282. raise DataError(errmsg + '(uploading appender)')
  283. tc = Tracker_client(self.tracker_pool)
  284. store_serv = tc.tracker_query_storage_stor_without_group()
  285. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  286. return store.storage_upload_appender_by_file(tc, store_serv, \
  287. local_filename, meta_dict)
  288. def upload_appender_by_buffer(self, filebuffer, file_ext_name = None, meta_dict = None):
  289. '''
  290. Upload a buffer to Storage server.
  291. arguments:
  292. @filebuffer: string
  293. @file_ext_name: string, can be null
  294. @meta_dict: dictionary, can be null
  295. @return dict {
  296. 'Group name' : group_name,
  297. 'Remote file_id' : remote_file_id,
  298. 'Status' : 'Upload successed.',
  299. 'Local file name' : '',
  300. 'Uploaded size' : upload_size,
  301. 'Storage IP' : storage_ip
  302. } if success else None
  303. '''
  304. if not filebuffer:
  305. raise DataError('[-] Error: argument filebuffer can not be null.')
  306. tc = Tracker_client(self.tracker_pool)
  307. store_serv = tc.tracker_query_storage_stor_without_group()
  308. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  309. return store.storage_upload_appender_by_buffer(tc, store_serv, \
  310. filebuffer, meta_dict, \
  311. file_ext_name)
  312. def delete_file(self, remote_file_id):
  313. '''
  314. Delete a file from Storage server.
  315. arguments:
  316. @remote_file_id: string, file_id of file that is on storage server
  317. @return tuple ('Delete file successed.', remote_file_id, storage_ip)
  318. '''
  319. tmp = split_remote_fileid(remote_file_id)
  320. if not tmp:
  321. raise DataError('[-] Error: remote_file_id is invalid.(in delete file)')
  322. group_name, remote_filename = tmp
  323. tc = Tracker_client(self.tracker_pool)
  324. store_serv = tc.tracker_query_storage_stor_with_group(group_name)
  325. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  326. return store.storage_delete_file(tc, store_serv, remote_filename)
  327. def download_to_file(self, local_filename, remote_file_id, offset = 0, down_bytes = 0):
  328. '''
  329. Download a file from Storage server.
  330. arguments:
  331. @local_filename: string, local name of file
  332. @remote_file_id: string, file_id of file that is on storage server
  333. @offset: long
  334. @downbytes: long
  335. @return dict {
  336. 'Remote file_id' : remote_file_id,
  337. 'Content' : local_filename,
  338. 'Download size' : downloaded_size,
  339. 'Storage IP' : storage_ip
  340. }
  341. '''
  342. tmp = split_remote_fileid(remote_file_id)
  343. if not tmp:
  344. raise DataError('[-] Error: remote_file_id is invalid.(in download file)')
  345. group_name, remote_filename = tmp
  346. if not offset:
  347. file_offset = long(offset)
  348. if not down_bytes:
  349. download_bytes = long(down_bytes)
  350. tc = Tracker_client(self.tracker_pool)
  351. store_serv = tc.tracker_query_storage_fetch(group_name, remote_filename)
  352. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  353. return store.storage_download_to_file(tc, store_serv, local_filename, \
  354. file_offset, download_bytes, \
  355. remote_filename)
  356. def download_to_buffer(self, remote_file_id, offset = 0, down_bytes = 0):
  357. '''
  358. Download a file from Storage server and store in buffer.
  359. arguments:
  360. @remote_file_id: string, file_id of file that is on storage server
  361. @offset: long
  362. @down_bytes: long
  363. @return dict {
  364. 'Remote file_id' : remote_file_id,
  365. 'Content' : file_buffer,
  366. 'Download size' : downloaded_size,
  367. 'Storage IP' : storage_ip
  368. }
  369. '''
  370. tmp = split_remote_fileid(remote_file_id)
  371. if not tmp:
  372. raise DataError('[-] Error: remote_file_id is invalid.(in download file)')
  373. group_name, remote_filename = tmp
  374. if not offset:
  375. file_offset = long(offset)
  376. if not down_bytes:
  377. download_bytes = long(down_bytes)
  378. tc = Tracker_client(self.tracker_pool)
  379. store_serv = tc.tracker_query_storage_fetch(group_name, remote_filename)
  380. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  381. file_buffer = None
  382. return store.storage_download_to_buffer(tc, store_serv, file_buffer, \
  383. file_offset, download_bytes, \
  384. remote_filename)
  385. def list_one_group(self, group_name):
  386. '''
  387. List one group information.
  388. arguments:
  389. @group_name: string, group name will be list
  390. @return Group_info, instance
  391. '''
  392. tc = Tracker_client(self.tracker_pool)
  393. return tc.tracker_list_one_group(group_name)
  394. def list_servers(self, group_name, storage_ip = None):
  395. '''
  396. List all storage servers information in a group
  397. arguments:
  398. @group_name: string
  399. @return dictionary {
  400. 'Group name' : group_name,
  401. 'Servers' : server list,
  402. }
  403. '''
  404. tc = Tracker_client(self.tracker_pool)
  405. return tc.tracker_list_servers(group_name, storage_ip)
  406. def list_all_groups(self):
  407. '''
  408. List all group information.
  409. @return dictionary {
  410. 'Groups count' : group_count,
  411. 'Groups' : list of groups
  412. }
  413. '''
  414. tc = Tracker_client(self.tracker_pool)
  415. return tc.tracker_list_all_groups()
  416. def get_meta_data(self, remote_file_id):
  417. '''
  418. Get meta data of remote file.
  419. arguments:
  420. @remote_fileid: string, remote file id
  421. @return dictionary, meta data
  422. '''
  423. tmp = split_remote_fileid(remote_file_id)
  424. if not tmp:
  425. raise DataError('[-] Error: remote_file_id is invalid.(in get meta data)')
  426. group_name, remote_filename = tmp
  427. tc = Tracker_client(self.tracker_pool)
  428. store_serv = tc.tracker_query_storage_update(group_name, remote_filename)
  429. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  430. return store.storage_get_metadata(tc, store_serv, remote_filename)
  431. def set_meta_data(self, remote_file_id, \
  432. meta_dict, op_flag = STORAGE_SET_METADATA_FLAG_OVERWRITE):
  433. '''
  434. Set meta data of remote file.
  435. arguments:
  436. @remote_file_id: string
  437. @meta_dict: dictionary
  438. @op_flag: char, 'O' for overwrite, 'M' for merge
  439. @return dictionary {
  440. 'Status' : status,
  441. 'Storage IP' : storage_ip
  442. }
  443. '''
  444. tmp = split_remote_fileid(remote_file_id)
  445. if not tmp:
  446. raise DataError('[-] Error: remote_file_id is invalid.(in set meta data)')
  447. group_name, remote_filename = tmp
  448. tc = Tracker_client(self.tracker_pool)
  449. try:
  450. store_serv = tc.tracker_query_storage_update(group_name, remote_filename)
  451. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  452. status = store.storage_set_metadata(tc, store_serv, \
  453. remote_filename, meta_dict)
  454. except (ConnectionError, ResponseError, DataError):
  455. raise
  456. #if status == 2:
  457. # raise DataError('[-] Error: remote file %s is not exist.' % remote_file_id)
  458. if status != 0:
  459. raise DataError('[-] Error: %d, %s' % (th.status, os.strerror(th.status)))
  460. ret_dict = {}
  461. ret_dict['Status'] = 'Set meta data success.'
  462. ret_dict['Storage IP'] = store_serv.ip_addr
  463. return ret_dict
  464. def append_by_filename(self, local_filename, remote_fileid):
  465. isfile, errmsg = fdfs_check_file(local_filename)
  466. if not isfile:
  467. raise DataError(errmsg + '(append)')
  468. tmp = split_remote_fileid(remote_fileid)
  469. if not tmp:
  470. raise DataError('[-] Error: remote_file_id is invalid.(append)')
  471. group_name, appended_filename = tmp
  472. tc = Tracker_client(self.tracker_pool)
  473. store_serv = tc.tracker_query_storage_update(group_name, appended_filename)
  474. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  475. return store.storage_append_by_filename(tc, store_serv, local_filename, \
  476. appended_filename)
  477. def append_by_file(self, local_filename, remote_fileid):
  478. isfile, errmsg = fdfs_check_file(local_filename)
  479. if not isfile:
  480. raise DataError(errmsg + '(append)')
  481. tmp = split_remote_fileid(remote_fileid)
  482. if not tmp:
  483. raise DataError('[-] Error: remote_file_id is invalid.(append)')
  484. group_name, appended_filename = tmp
  485. tc = Tracker_client(self.tracker_pool)
  486. store_serv = tc.tracker_query_storage_update(group_name, appended_filename)
  487. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  488. return store.storage_append_by_file(tc, store_serv, local_filename, \
  489. appended_filename)
  490. def append_by_buffer(self, file_buffer, remote_fileid):
  491. if not file_buffer:
  492. raise DataError('[-] Error: file_buffer can not be null.')
  493. tmp = split_remote_fileid(remote_fileid)
  494. if not tmp:
  495. raise DataError('[-] Error: remote_file_id is invalid.(append)')
  496. group_name, appended_filename = tmp
  497. tc = Tracker_client(self.tracker_pool)
  498. store_serv = tc.tracker_query_storage_update(group_name, appended_filename)
  499. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  500. return store.storage_append_by_buffer(tc, store_serv, file_buffer, \
  501. appended_filename)
  502. def truncate_file(self, truncated_filesize, appender_fileid):
  503. '''
  504. Truncate file in Storage server.
  505. arguments:
  506. @truncated_filesize: long
  507. @appender_fileid: remote_fileid
  508. @return: dictionary {
  509. 'Status' : 'Truncate successed.',
  510. 'Storage IP' : storage_ip
  511. }
  512. '''
  513. trunc_filesize = long(truncated_filesize)
  514. tmp = split_remote_fileid(appender_fileid)
  515. if not tmp:
  516. raise DataError('[-] Error: appender_fileid is invalid.(truncate)')
  517. group_name, appender_filename = tmp
  518. tc = Tracker_client(self.tracker_pool)
  519. store_serv = tc.tracker_query_storage_update(group_name, appender_filename)
  520. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  521. return store.storage_truncate_file(tc, store_serv, trunc_filesize, \
  522. appender_filename)
  523. def modify_by_filename(self, filename, appender_fileid, offset = 0):
  524. '''
  525. Modify a file in Storage server by file.
  526. arguments:
  527. @filename: string, local file name
  528. @offset: long, file offset
  529. @appender_fileid: string, remote file id
  530. @return: dictionary {
  531. 'Status' : 'Modify successed.',
  532. 'Storage IP' : storage_ip
  533. }
  534. '''
  535. isfile, errmsg = fdfs_check_file(filename)
  536. if not isfile:
  537. raise DataError(errmsg + '(modify)')
  538. filesize = os.stat(filename).st_size
  539. tmp = split_remote_fileid(appender_fileid)
  540. if not tmp:
  541. raise DataError('[-] Error: remote_fileid is invalid.(modify)')
  542. group_name, appender_filename = tmp
  543. if not offset:
  544. file_offset = long(offset)
  545. else:
  546. file_offset = 0
  547. tc = Tracker_client(self.tracker_pool)
  548. store_serv = tc.tracker_query_storage_update(group_name, appender_filename)
  549. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  550. return store.storage_modify_by_filename(tc, store_serv, filename, file_offset, \
  551. filesize, appender_filename)
  552. def modify_by_file(self, filename, appender_fileid, offset = 0):
  553. '''
  554. Modify a file in Storage server by file.
  555. arguments:
  556. @filename: string, local file name
  557. @offset: long, file offset
  558. @appender_fileid: string, remote file id
  559. @return: dictionary {
  560. 'Status' : 'Modify successed.',
  561. 'Storage IP' : storage_ip
  562. }
  563. '''
  564. isfile, errmsg = fdfs_check_file(filename)
  565. if not isfile:
  566. raise DataError(errmsg + '(modify)')
  567. filesize = os.stat(filename).st_size
  568. tmp = split_remote_fileid(appender_fileid)
  569. if not tmp:
  570. raise DataError('[-] Error: remote_fileid is invalid.(modify)')
  571. group_name, appender_filename = tmp
  572. if not offset:
  573. file_offset = long(offset)
  574. else:
  575. file_offset = 0
  576. tc = Tracker_client(self.tracker_pool)
  577. store_serv = tc.tracker_query_storage_update(group_name, appender_filename)
  578. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  579. return store.storage_modify_by_file(tc, store_serv, filename, file_offset, \
  580. filesize, appender_filename)
  581. def modify_by_buffer(self, filebuffer, appender_fileid, offset = 0):
  582. '''
  583. Modify a file in Storage server by buffer.
  584. arguments:
  585. @filebuffer: string, file buffer
  586. @offset: long, file offset
  587. @appender_fileid: string, remote file id
  588. @return: dictionary {
  589. 'Status' : 'Modify successed.',
  590. 'Storage IP' : storage_ip
  591. }
  592. '''
  593. if not filebuffer:
  594. raise DataError('[-] Error: filebuffer can not be null.(modify)')
  595. filesize = len(filebuffer)
  596. tmp = split_remote_fileid(appender_fileid)
  597. if not tmp:
  598. raise DataError('[-] Error: remote_fileid is invalid.(modify)')
  599. group_name, appender_filename = tmp
  600. if not offset:
  601. file_offset = long(offset)
  602. else:
  603. file_offset = 0
  604. tc = Tracker_client(self.tracker_pool)
  605. store_serv = tc.tracker_query_storage_update(group_name, appender_filename)
  606. store = Storage_client(store_serv.ip_addr, store_serv.port, self.timeout)
  607. return store.storage_modify_by_buffer(tc, store_serv, filebuffer, file_offset, \
  608. filesize, appender_filename)