Coverage for cookbook/provider/nextcloud.py: 33%

78 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2023-12-29 00:47 +0100

1import io 

2import os 

3import tempfile 

4from datetime import datetime 

5 

6import requests 

7import validators 

8import webdav3.client as wc 

9from cookbook.models import Recipe, RecipeImport, SyncLog 

10from cookbook.provider.provider import Provider 

11from requests.auth import HTTPBasicAuth 

12 

13from recipes.settings import DEBUG 

14 

15 

16class Nextcloud(Provider): 

17 

18 @staticmethod 

19 def get_client(storage): 

20 options = { 

21 'webdav_hostname': storage.url, 

22 'webdav_login': storage.username, 

23 'webdav_password': storage.password, 

24 'webdav_root': '/remote.php/dav/files/' + storage.username 

25 } 

26 if storage.path != '': 

27 options['webdav_root'] = storage.path 

28 return wc.Client(options) 

29 

30 @staticmethod 

31 def import_all(monitor): 

32 client = Nextcloud.get_client(monitor.storage) 

33 

34 if DEBUG: 

35 print(f'TANDOOR_PROVIDER_DEBUG checking path {monitor.path} with client {client}') 

36 

37 files = client.list(monitor.path) 

38 

39 if DEBUG: 

40 print(f'TANDOOR_PROVIDER_DEBUG file list {files}') 

41 

42 import_count = 0 

43 for file in files: 

44 if DEBUG: 

45 print(f'TANDOOR_PROVIDER_DEBUG importing file {file}') 

46 path = monitor.path + '/' + file 

47 if not Recipe.objects.filter(file_path__iexact=path, space=monitor.space).exists() and not RecipeImport.objects.filter(file_path=path, space=monitor.space).exists(): 

48 name = os.path.splitext(file)[0] 

49 new_recipe = RecipeImport( 

50 name=name, 

51 file_path=path, 

52 storage=monitor.storage, 

53 space=monitor.space, 

54 ) 

55 new_recipe.save() 

56 import_count += 1 

57 

58 log_entry = SyncLog( 

59 status='SUCCESS', 

60 msg='Imported ' + str(import_count) + ' recipes', 

61 sync=monitor, 

62 ) 

63 log_entry.save() 

64 

65 monitor.last_checked = datetime.now() 

66 monitor.save() 

67 

68 return True 

69 

70 @staticmethod 

71 def create_share_link(recipe): 

72 url = recipe.storage.url + '/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json' # noqa: E501 

73 

74 headers = { 

75 "OCS-APIRequest": "true", 

76 "Content-Type": "application/x-www-form-urlencoded" 

77 } 

78 

79 data = {'path': recipe.file_path, 'shareType': 3} 

80 

81 r = requests.post(url, headers=headers, auth=HTTPBasicAuth(recipe.storage.username, recipe.storage.password), data=data) 

82 

83 response_json = r.json() 

84 

85 return response_json['ocs']['data']['url'] 

86 

87 @staticmethod 

88 def get_share_link(recipe): 

89 url = recipe.storage.url + '/ocs/v2.php/apps/files_sharing/api/v1/shares?format=json&path=' + recipe.file_path # noqa: E501 

90 

91 headers = { 

92 "OCS-APIRequest": "true", 

93 "Content-Type": "application/json" 

94 } 

95 

96 if validators.url(url, public=True): 

97 r = requests.get( 

98 url, 

99 headers=headers, 

100 auth=HTTPBasicAuth( 

101 recipe.storage.username, recipe.storage.password 

102 ) 

103 ) 

104 

105 response_json = r.json() 

106 for element in response_json['ocs']['data']: 

107 if element['share_type'] == '3': 

108 return element['url'] 

109 

110 return Nextcloud.create_share_link(recipe) 

111 

112 @staticmethod 

113 def get_file(recipe): 

114 client = Nextcloud.get_client(recipe.storage) 

115 

116 tmp_file_path = tempfile.gettempdir() + '/' + recipe.name + '.pdf' 

117 

118 client.download_file( 

119 remote_path=recipe.file_path, 

120 local_path=tmp_file_path 

121 ) 

122 

123 file = io.BytesIO(open(tmp_file_path, 'rb').read()) 

124 os.remove(tmp_file_path) 

125 

126 return file 

127 

128 @staticmethod 

129 def rename_file(recipe, new_name): 

130 client = Nextcloud.get_client(recipe.storage) 

131 

132 client.move( 

133 recipe.file_path, 

134 "%s/%s%s" % ( 

135 os.path.dirname(recipe.file_path), 

136 new_name, 

137 os.path.splitext(recipe.file_path)[1] 

138 ) 

139 ) 

140 

141 return True 

142 

143 @staticmethod 

144 def delete_file(recipe): 

145 client = Nextcloud.get_client(recipe.storage) 

146 

147 client.clean(recipe.file_path) 

148 

149 return True