@@ -670,7 +670,7 @@ defmodule WraftDoc.TemplateAssets do
670670
671671 defp get_theme_font_file_entries ( entries ) do
672672 Enum . filter ( entries , fn entry ->
673- case Regex . run ( ~r/ ^theme \/ .*-(?<style>\w +)\. (otf|ttf)$/ i , entry . file_name ) do
673+ case Regex . run ( ~r/ ^fonts \/ .*-(?<style>\w +)\. (otf|ttf)$/ i , entry . file_name ) do
674674 [ _ , style , _ ] when style in @ font_style_name -> true
675675 _ -> false
676676 end
@@ -753,18 +753,20 @@ defmodule WraftDoc.TemplateAssets do
753753 frame_id
754754 ) do
755755 with % Engine { id: engine_id } <- get_engine ( engine ) ,
756- asset_id <- prepare_layout_assets ( entries , file_path , downloaded_file , current_user ) ,
757- params <- prepare_layout_attrs ( layouts , engine_id , asset_id , frame_id ) ,
756+ asset_params <-
757+ prepare_layout_assets_params ( entries , file_path , downloaded_file ) ,
758+ params <- prepare_layout_attrs ( layouts , engine_id , frame_id ) ,
758759 % Engine { } = engine <- Frames . get_engine_by_frame_type ( params ) ,
759- % Layout { } = layout <- Layouts . create_layout ( current_user , engine , params ) do
760+ { :ok , % { layout: layout } } <-
761+ Layouts . create_layout ( current_user , engine , Map . merge ( params , asset_params ) ) do
760762 { :ok , layout }
761763 end
762764 end
763765
764- defp prepare_layout_assets ( entries , file_path , downloaded_file , current_user ) do
766+ defp prepare_layout_assets_params ( entries , file_path , downloaded_file ) do
765767 entries
766768 |> get_layout_file_entry ( file_path )
767- |> extract_and_prepare_layout_asset ( downloaded_file , current_user )
769+ |> extract_and_prepare_layout_asset ( downloaded_file )
768770 end
769771
770772 defp get_pdf_asset_path ( assets , type ) do
@@ -773,14 +775,13 @@ defmodule WraftDoc.TemplateAssets do
773775 end ) [ "path" ]
774776 end
775777
776- defp prepare_layout_attrs ( layout , engine_id , asset_id , frame_id ) do
778+ defp prepare_layout_attrs ( layout , engine_id , frame_id ) do
777779 % {
778780 "name" => layout [ "name" ] ,
779781 "meta" => layout [ "meta" ] ,
780782 "description" => layout [ "description" ] ,
781783 "slug" => layout [ "slug" ] ,
782784 "engine_id" => engine_id ,
783- "assets" => asset_id ,
784785 "width" => 40 ,
785786 "height" => 40 ,
786787 "unit" => "cm" ,
@@ -794,12 +795,10 @@ defmodule WraftDoc.TemplateAssets do
794795 end )
795796 end
796797
797- defp extract_and_prepare_layout_asset ( entry , downloaded_zip_file , current_user ) do
798+ defp extract_and_prepare_layout_asset ( entry , downloaded_zip_file ) do
798799 with { :ok , content } <- FileHelper . extract_file_content ( downloaded_zip_file , entry . file_name ) ,
799- { :ok , temp_file_path } <- write_temp_file ( content ) ,
800- asset_params <- prepare_layout_asset_params ( entry , temp_file_path , current_user ) ,
801- { :ok , asset } <- Assets . create_asset ( current_user , asset_params ) do
802- asset . id
800+ { :ok , temp_file_path } <- write_temp_file ( content ) do
801+ prepare_layout_asset_params ( entry , temp_file_path )
803802 else
804803 error ->
805804 Logger . error (
@@ -810,16 +809,15 @@ defmodule WraftDoc.TemplateAssets do
810809 end
811810 end
812811
813- defp prepare_layout_asset_params ( entry , temp_file_path , current_user ) do
812+ defp prepare_layout_asset_params ( entry , temp_file_path ) do
814813 % {
815- "name " => Path . basename ( entry . file_name ) ,
814+ "asset_name " => Path . basename ( entry . file_name ) ,
816815 "type" => "layout" ,
817816 "file" => % Plug.Upload {
818817 filename: Path . basename ( entry . file_name ) ,
819818 content_type: get_file_type ( entry . file_name ) ,
820819 path: temp_file_path
821- } ,
822- "creator_id" => current_user . id
820+ }
823821 }
824822 end
825823
@@ -916,7 +914,7 @@ defmodule WraftDoc.TemplateAssets do
916914 defp get_data_template_prosemirror ( downloaded_file ) do
917915 with { :ok , template_json } <-
918916 FileHelper . extract_file_content ( downloaded_file , "template.json" ) ,
919- serialized_prosemirror <- Jason . decode! ( template_json ) do
917+ { :ok , serialized_prosemirror } <- Jason . decode ( template_json ) do
920918 { :ok , serialized_prosemirror [ "data" ] }
921919 end
922920 end
@@ -937,14 +935,14 @@ defmodule WraftDoc.TemplateAssets do
937935 defp validate_file_entries ( wraft_json , entries ) do
938936 items = has_items ( wraft_json )
939937
940- { folders , files } =
938+ { _folders , files } =
941939 Enum . split_with ( entries , fn entry ->
942940 String . ends_with? ( entry , "/" )
943941 end )
944942
945943 [ ]
946944 |> collect_missing_files ( files )
947- |> collect_missing_folders ( folders , items )
945+ |> collect_missing_folders ( items , files )
948946 |> validate_layout ( files , items )
949947 |> validate_theme ( files , items )
950948 |> validate_data_template ( files , items )
@@ -964,17 +962,19 @@ defmodule WraftDoc.TemplateAssets do
964962 errors ++ missing_files
965963 end
966964
967- defp collect_missing_folders ( errors , folders , items ) do
968- missing_folders =
969- items
970- |> Enum . flat_map ( fn
965+ defp collect_missing_folders ( errors , items , files ) do
966+ required_folders =
967+ Enum . flat_map ( items , fn
971968 "theme" -> [ "fonts/" ]
972969 "layout" -> [ "assets/" ]
973970 "frame" -> [ "frame/" ]
974971 _ -> [ ]
975972 end )
976- |> Enum . filter ( fn folder ->
977- not Enum . any? ( folders , & String . starts_with? ( & 1 , folder ) )
973+
974+ missing_folders =
975+ required_folders
976+ |> Enum . reject ( fn folder ->
977+ Enum . any? ( files , & String . starts_with? ( & 1 , folder ) )
978978 end )
979979 |> Enum . map ( & % { type: "folder_error" , message: "Missing required folder: #{ & 1 } " } )
980980
@@ -1174,20 +1174,26 @@ defmodule WraftDoc.TemplateAssets do
11741174 Prepare all the nessecary files and format for zip export.
11751175 """
11761176 def prepare_template_format ( theme , layout , c_type , data_template , current_user ) do
1177- folder_path = data_template . title
1178- File . mkdir_p! ( folder_path )
1177+ case validate_template_inputs ( theme , layout , c_type , data_template ) do
1178+ { :ok , _validated } ->
1179+ folder_path = data_template . title
1180+ File . mkdir_p! ( folder_path )
11791181
1180- case create_wraft_json ( theme , layout , c_type , data_template , folder_path , current_user ) do
1181- :ok ->
1182- template_name = "#{ data_template . title } .zip"
1183- { :ok , zip_path } = zip_folder ( folder_path , template_name )
1182+ case create_wraft_json ( theme , layout , c_type , data_template , folder_path , current_user ) do
1183+ :ok ->
1184+ template_name = "#{ data_template . title } .zip"
1185+ { :ok , zip_path } = zip_folder ( folder_path , template_name )
11841186
1185- File . rm_rf ( folder_path )
1186- { :ok , zip_path }
1187+ File . rm_rf ( folder_path )
1188+ { :ok , zip_path }
1189+
1190+ { :error , reason } ->
1191+ File . rm_rf ( folder_path )
1192+ { :error , "Failed to prepare template: #{ reason } " }
1193+ end
11871194
11881195 { :error , reason } ->
1189- File . rm_rf ( folder_path )
1190- { :error , "Failed to prepare template: #{ reason } " }
1196+ { :error , "Invalid template data: #{ reason } " }
11911197 end
11921198 end
11931199
@@ -1206,18 +1212,67 @@ defmodule WraftDoc.TemplateAssets do
12061212
12071213 defp zip_folder ( folder_path , template_name ) do
12081214 zip_path = Path . join ( System . tmp_dir! ( ) , "#{ template_name } .zip" )
1209- :zip . create ( String . to_charlist ( zip_path ) , [ String . to_charlist ( folder_path ) ] )
1210- { :ok , zip_path }
1215+
1216+ files =
1217+ folder_path
1218+ |> Path . join ( "**" )
1219+ |> Path . wildcard ( )
1220+ |> Enum . filter ( & File . regular? / 1 )
1221+ |> Enum . map ( fn file ->
1222+ relative = Path . relative_to ( file , folder_path )
1223+ { :ok , bin } = File . read ( file )
1224+ { String . to_charlist ( relative ) , bin }
1225+ end )
1226+
1227+ case :zip . create ( String . to_charlist ( zip_path ) , files , [ :memory ] ) do
1228+ { :ok , { _zip_name , zip_binary } } ->
1229+ File . write! ( zip_path , zip_binary )
1230+ { :ok , zip_path }
1231+
1232+ { :error , reason } ->
1233+ { :error , reason }
1234+ end
12111235 end
12121236
12131237 def build_wraft_json ( theme , layout , c_type , data_template , file_path , current_user ) do
12141238 % {
1215- "theme" => build_theme ( theme , file_path , current_user ) ,
1216- "layout" => build_layout ( layout , file_path , current_user ) ,
1217- "variant" => build_c_type ( c_type ) ,
1218- "data_template" => % {
1219- "title" => data_template . title ,
1220- "title_template" => data_template . title_template
1239+ "metadata" => % {
1240+ "name" => export_to_markdown ( data_template , file_path ) <> " template" ,
1241+ "description" => "Template for #{ data_template . title } " ,
1242+ "type" => "template_asset" ,
1243+ "updated_at" => Date . to_string ( Date . utc_today ( ) )
1244+ } ,
1245+ "packageContents" => % {
1246+ "rootFiles" => [
1247+ % { "name" => "template.json" , "path" => "template.json" } ,
1248+ % { "name" => "wraft.json" , "path" => "wraft.json" }
1249+ ] ,
1250+ "assets" => [
1251+ % {
1252+ "name" => "#{ layout . name } " ,
1253+ "path" => "assets/letterhead.pdf" ,
1254+ "type" => "layout" ,
1255+ "description" => "#{ layout . description } "
1256+ }
1257+ ] ,
1258+ "fonts" =>
1259+ Enum . map ( theme . assets , fn asset ->
1260+ % {
1261+ "fontName" => asset . name ,
1262+ "fontWeight" => "regular" ,
1263+ "path" => download_file ( asset . id , current_user , file_path , "fonts" )
1264+ }
1265+ end )
1266+ } ,
1267+ "items" => % {
1268+ "theme" => build_theme ( theme , file_path , current_user ) ,
1269+ "layout" => build_layout ( layout , file_path , current_user ) ,
1270+ "flow" => % { "name" => "Wraft flow" } ,
1271+ "variant" => build_c_type ( c_type ) ,
1272+ "data_template" => % {
1273+ "title" => data_template . title ,
1274+ "title_template" => data_template . title_template
1275+ }
12211276 }
12221277 }
12231278 end
@@ -1231,26 +1286,30 @@ defmodule WraftDoc.TemplateAssets do
12311286 Enum . map ( theme . assets , fn asset ->
12321287 % {
12331288 "fontName" => asset . name ,
1234- "filePath " => download_file ( asset . id , current_user , file_path , "otf" , "theme ")
1289+ "path " => download_file ( asset . id , current_user , file_path , "fonts " )
12351290 }
12361291 end ) ,
1237- "color " => % {
1238- "body_color " => theme . body_color ,
1239- "primary_color " => theme . primary_color ,
1240- "secondary_color " => theme . secondary_color
1292+ "colors " => % {
1293+ "bodyColor " => theme . body_color ,
1294+ "primaryColor " => theme . primary_color ,
1295+ "secondaryColor " => theme . secondary_color
12411296 }
12421297 }
12431298 end
12441299
12451300 defp build_layout ( layout , file_path , current_user ) do
1246- layout = Repo . preload ( layout , :assets )
1247- [ asset | _ ] = layout . assets
1301+ layout = Repo . preload ( layout , :asset )
1302+ asset = layout . asset
12481303
12491304 % {
12501305 "name" => layout . name ,
1251- "slug" => make_slug ( layout . slug , file_path ) ,
1252- "slug_file" => download_file ( asset . id , current_user , file_path , "pdf" , "layout" ) ,
1253- "meta" => "fields" ,
1306+ "slug" => "#{ layout . slug } " ,
1307+ "slug_file" => download_file ( asset . id , current_user , file_path , "assets" ) ,
1308+ "meta" => % {
1309+ "standard_size" => "a4" ,
1310+ "fields" => [ ] ,
1311+ "margin" => "2.54"
1312+ } ,
12541313 "description" => layout . description ,
12551314 "engine" => "pandoc/latex"
12561315 }
@@ -1269,31 +1328,76 @@ defmodule WraftDoc.TemplateAssets do
12691328 % {
12701329 "name" => field . name ,
12711330 "description" => field . description ,
1272- "type" => field . field_type . name
1331+ "type" => String . downcase ( field . field_type . name )
12731332 }
12741333 end )
12751334 }
12761335 end
12771336
1278- defp make_slug ( slug , file_path ) do
1279- path = :wraft_doc |> :code . priv_dir ( ) |> Path . join ( "slugs/#{ slug } /." )
1280- System . cmd ( "cp" , [ "-a" , path , file_path <> "/" <> slug ] )
1281- slug
1337+ defp export_to_markdown ( template , folder_path ) do
1338+ template_json = """
1339+ {"data": #{ Jason . encode! ( template . serialized [ "data" ] ) } }
1340+ """
1341+
1342+ folder_path
1343+ |> Path . join ( "template.json" )
1344+ |> File . write! ( template_json )
1345+
1346+ markdown =
1347+ template . serialized [ "data" ]
1348+ |> Jason . decode! ( )
1349+ |> ProsemirrorToMarkdown . convert ( )
1350+
1351+ File . write! ( Path . join ( folder_path , "template.md" ) , markdown )
1352+
1353+ template . title
1354+ end
1355+
1356+ defp validate_template_inputs ( theme , layout , c_type , data_template ) do
1357+ with { :ok , data_template } <- validate_data_template ( data_template ) ,
1358+ { :ok , theme } <- validate_theme ( theme ) ,
1359+ { :ok , layout } <- validate_layout ( layout ) ,
1360+ { :ok , c_type } <- validate_contract_type ( c_type ) do
1361+ { :ok , % { theme: theme , layout: layout , c_type: c_type , data_template: data_template } }
1362+ end
12821363 end
12831364
1365+ defp validate_data_template ( nil ) , do: { :error , "DataTemplate is missing" }
1366+ defp validate_data_template ( % { title: nil } ) , do: { :error , "DataTemplate title is missing" }
1367+ defp validate_data_template ( % { title: "" } ) , do: { :error , "DataTemplate title is missing" }
1368+
1369+ defp validate_data_template ( % { serialized: nil } ) ,
1370+ do: { :error , "DataTemplate serialized data is missing" }
1371+
1372+ defp validate_data_template ( dt ) , do: { :ok , dt }
1373+
1374+ defp validate_theme ( nil ) , do: { :error , "Theme is missing" }
1375+ defp validate_theme ( % { name: nil } ) , do: { :error , "Theme name is missing" }
1376+ defp validate_theme ( % { assets: nil } ) , do: { :error , "Theme assets missing" }
1377+ defp validate_theme ( % { assets: [ ] } ) , do: { :error , "Theme assets missing" }
1378+ defp validate_theme ( theme ) , do: { :ok , theme }
1379+
1380+ defp validate_layout ( nil ) , do: { :error , "Layout is missing" }
1381+ defp validate_layout ( % { name: nil } ) , do: { :error , "Layout name is missing" }
1382+ defp validate_layout ( % { asset: nil } ) , do: { :error , "Layout asset is missing" }
1383+ defp validate_layout ( layout ) , do: { :ok , layout }
1384+
1385+ defp validate_contract_type ( nil ) , do: { :error , "Contract type is missing" }
1386+ defp validate_contract_type ( % { name: nil } ) , do: { :error , "Contract type name is missing" }
1387+ defp validate_contract_type ( c_type ) , do: { :ok , c_type }
1388+
12841389 defp download_file (
12851390 asset_id ,
12861391 % { current_org_id: org_id } = _current_user ,
12871392 file_path ,
1288- format ,
12891393 folder_name
12901394 ) do
1291- file = Minio . download ( "organisations/#{ org_id } /assets/#{ asset_id } " )
12921395 asset = Assets . get_asset ( asset_id , % { current_org_id: org_id } )
1293- path = "#{ file_path } /#{ folder_name } /#{ asset . name } .#{ format } "
1396+ file = Minio . download ( "organisations/#{ org_id } /assets/#{ asset_id } /#{ asset . file . file_name } " )
1397+ path = "#{ file_path } /#{ folder_name } /#{ asset . file . file_name } "
12941398 File . mkdir_p ( Path . dirname ( path ) )
12951399 File . write! ( path , file )
1296- "#{ folder_name } /#{ asset . name } . #{ format } "
1400+ "#{ folder_name } /#{ asset . file . file_name } "
12971401 end
12981402
12991403 defp update_conflicting_name ( % { "title" => title } = map , DataTemplate , current_user ) do
0 commit comments