client.py 26 KB

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