__main__.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import gi
  2. gi.require_version("Gtk", "3.0")
  3. from gi.repository import GLib, Gio, Gtk
  4. import sys
  5. import os
  6. from ppublisher.file_item import FileItem
  7. from ppublisher.metadata import MetadataEditor
  8. from ppublisher.file_editor import FileEditor
  9. from PyPPUB import ppub_builder
  10. #
  11. # 1. our .glade file (may contain paths)
  12. #
  13. @Gtk.Template.from_file("ppublisher/ppublisher.ui")
  14. class AppWindow(Gtk.ApplicationWindow):
  15. #
  16. # 2. the GtkApplicationWindow class
  17. #
  18. __gtype_name__ = "ppublisher"
  19. #
  20. # 3. the Button id
  21. #
  22. editor: Gtk.Box = Gtk.Template.Child()
  23. file_list: Gtk.ListBox = Gtk.Template.Child()
  24. def __init__(self, **kwargs):
  25. super(Gtk.ApplicationWindow, self).__init__(**kwargs)
  26. self.current_editor = None
  27. def set_editor(self, child):
  28. if(self.current_editor != None):
  29. self.editor.remove(self.current_editor)
  30. self.current_editor = child
  31. self.editor.add(child)
  32. def get_all_items(self):
  33. return [x.get_child() for x in self.file_list.get_children()]
  34. def set_default_document(self, item):
  35. items = self.get_all_items()
  36. for i in items:
  37. i.set_main(False)
  38. if(item != None):
  39. item.set_main(True)
  40. def get_default_document(self):
  41. items = self.get_all_items()
  42. for item in items:
  43. if(item.is_main):
  44. return item
  45. return None
  46. def get_metadata(self):
  47. items = self.get_all_items()
  48. for item in items:
  49. if(item.is_metadata):
  50. return item
  51. return None
  52. def build_ppub(self, path):
  53. metadata = self.get_metadata()
  54. default = self.get_default_document()
  55. if(metadata == None or default == None):
  56. raise Exception("No default document or metadata present!")
  57. builder = ppub_builder.PpubBuilder()
  58. builder.metadata = metadata.build_metadata()
  59. self.add_asset(builder, default)
  60. for item in self.get_all_items():
  61. if(item == metadata or item == default):
  62. continue
  63. self.add_asset(builder, item)
  64. f = open(path, 'wb')
  65. builder.write_to_stream(f)
  66. f.close()
  67. def add_asset(self, builder, item):
  68. f = open(item.path, 'rb')
  69. builder.add_asset(item.filename, item.mimetype, f.read())
  70. def build_ppix(self, folder_path):
  71. from PyPPUB.ppix_builder import PpixBuilder
  72. from PyPPUB import ppub
  73. builder = PpixBuilder()
  74. import glob
  75. paths = glob.glob(folder_path + "/*.ppub")
  76. paths = sorted(paths, key= lambda p: os.stat(p).st_ctime, reverse=True)
  77. for path in paths:
  78. builder.add_publication(path.split("/")[-1], ppub.Ppub.from_stream(open(path, 'rb')))
  79. f = open(folder_path + "/lib.ppix", 'wb')
  80. builder.write_out(f)
  81. @Gtk.Template.Callback()
  82. def file_selected(self, widget, list_item):
  83. item = list_item.get_child()
  84. if(item.is_metadata):
  85. self.set_editor(MetadataEditor(item))
  86. else:
  87. self.set_editor(FileEditor(item, self))
  88. @Gtk.Template.Callback()
  89. def add_file_click(self, widget):
  90. dialog = Gtk.FileChooserDialog(title = "Add File", parent = self, action = Gtk.FileChooserAction.OPEN)
  91. dialog.add_buttons(
  92. Gtk.STOCK_CANCEL,
  93. Gtk.ResponseType.CANCEL,
  94. Gtk.STOCK_OPEN,
  95. Gtk.ResponseType.OK,
  96. )
  97. dialog.set_select_multiple(True)
  98. response = dialog.run()
  99. if response == Gtk.ResponseType.OK:
  100. files = dialog.get_filenames()
  101. for file in files:
  102. print(file)
  103. self.file_list.add(FileItem(file))
  104. dialog.destroy()
  105. @Gtk.Template.Callback()
  106. def save_click(self, widget):
  107. dialog = Gtk.FileChooserDialog(title = "Save PPUB", parent = self, action = Gtk.FileChooserAction.SAVE)
  108. dialog.add_buttons(
  109. Gtk.STOCK_CANCEL,
  110. Gtk.ResponseType.CANCEL,
  111. Gtk.STOCK_SAVE,
  112. Gtk.ResponseType.OK,
  113. )
  114. response = dialog.run()
  115. if response == Gtk.ResponseType.OK:
  116. try:
  117. self.build_ppub(dialog.get_filename())
  118. except Exception as ex:
  119. error = Gtk.MessageDialog(
  120. transient_for=dialog,
  121. flags=0,
  122. message_type=Gtk.MessageType.ERROR,
  123. buttons=Gtk.ButtonsType.CANCEL,
  124. text="Error exporting PPUB!",
  125. )
  126. error.format_secondary_text(str(ex))
  127. error.run()
  128. error.destroy()
  129. dialog.destroy()
  130. @Gtk.Template.Callback()
  131. def create_index_click(self, widget):
  132. dialog = Gtk.FileChooserDialog(title = "Choose a file to build a PPIX index in", parent = self, action = Gtk.FileChooserAction.SELECT_FOLDER)
  133. dialog.add_buttons(
  134. Gtk.STOCK_CANCEL,
  135. Gtk.ResponseType.CANCEL,
  136. "Build Index",
  137. Gtk.ResponseType.OK,
  138. )
  139. response = dialog.run()
  140. if response == Gtk.ResponseType.OK:
  141. try:
  142. self.build_ppix(dialog.get_filename())
  143. except Exception as ex:
  144. error = Gtk.MessageDialog(
  145. transient_for=dialog,
  146. flags=0,
  147. message_type=Gtk.MessageType.ERROR,
  148. buttons=Gtk.ButtonsType.CANCEL,
  149. text="Error creating PPIX!",
  150. )
  151. error.format_secondary_text(str(ex))
  152. error.run()
  153. error.destroy()
  154. dialog.destroy()
  155. @Gtk.Template.Callback()
  156. def remove_file_click(self, widget):
  157. item_container = self.file_list.get_selected_row()
  158. item = item_container.get_child()
  159. if(item.is_metadata):
  160. return
  161. self.file_list.remove(item_container)
  162. class Application(Gtk.Application):
  163. def __init__(self, *args, **kwargs):
  164. super().__init__(*args, application_id="com.pcthingz.ppublisher",
  165. flags=Gio.ApplicationFlags.FLAGS_NONE, **kwargs)
  166. self.window = None
  167. def do_activate(self):
  168. self.window = self.window or AppWindow(application=self)
  169. self.window.present()
  170. self.window.file_list.add(FileItem(None, True))
  171. if __name__ == '__main__':
  172. Application().run(sys.argv)