# Copyright (C) 2009, Tutorius.org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA """ WorkshopModel This module is the model of the Workshop Activity """ from sugar.tutorius.vault import * from sugar.tutorius.store import * from dialogs import LoginDialog,WaitingDialog,ErrorDialog import gtk import threading from copy import deepcopy import gobject import sys,traceback import logging class Login(object): def __init__(self,proxy,login_view): self.proxy = proxy self.login_view = login_view def __call__(self,f): def wrapper(*args): self.model = self.login_view.get_model() self.login_view = LoginDialog() self.login_view.set_model(self.model) if self.proxy.get_session_id() == None: result = self.login_view.run() self.login_view.destroy() if result == gtk.RESPONSE_ACCEPT: f(*args) else: f(*args) return wrapper class WorkshopModel(): store_proxy = StoreProxy("http://bobthebuilder.mine.nu/tutorius/en-US/tutorius") login_view = LoginDialog() def __init__(self): self.login_view.set_model(self) self.store_page_number = 1 def set_workshop_view(self,view): self.workshop_view = view def set_store_view(self,view): self.store_view = view def login(self,username,password): """ Log a user in the store @param username The username of the user @param password The password of the user @return True if login succeeded False otherwise """ return self.store_proxy.login(username,password) def register(self,username,password,email): """ Register a new user to the store @param username The username of the new user @param password The password of the user @param email The email of the user @return True if user is registered, False otherwise """ return self.store_proxy.register_new_user({'nickname':username,'password':password,'email':email}) def query(self,keyword): """ Query the vault for tutorial that are linked with the keyword Update the currently managed tutorials and notifies the view that the managed tutorials have changed @param keyword the keyword for the query """ if keyword is None or keyword == []: vault_return = Vault.query() else: vault_return = Vault.query(keyword=keyword) tutorial_list = [] for tuto in vault_return: tutorial_list.append(Tutorial(tuto)) self.workshop_view.set_tutorial_list(tutorial_list) def delete_tutorial(self,tutorial): """ Delete a tutorial and updated the currently managed tutorials Notifies the view that the manages tutorials have changed @param tutorial the tutorial to delete """ Vault.deleteTutorial(tutorial.id) self.query(None) self.workshop_view.display_main_view() def update_tutorial_infos(self,tutorial, new_infos): """ Updates the metadata on a tutorial and updates the currently managed tutorials Notifies the view that the managed tutorials have changed @param tutorial the tutorial to update @param new_infos a dictionnary of the new informations i.e. {"title":"tut1","author":"Max Power"} """ Vault.update_metadata(tutorial.id, tutorial.updated_metadata) @Login(store_proxy,login_view) def publish_tutorial(self,tutorial): """ Publishes a tutorial Details to come """ archive = Vault.get_tutorial_archive(tutorial.id) metadata = self.tutorial_to_store_metadata(tutorial) if not tutorial.published_state: remote_id = self.store_proxy.publish(archive,metadata) else: remote_id = self.store_proxy.update_published_tutorial(archive,metadata,tutorial.remote_id) if remote_id == -1: dialog = ErrorDialog("An error occured while publishing the tutorial") dialog.run() dialog.destroy() return tutorial.remote_id = remote_id tutorial.published_state = True metadata = self.tutorial_to_vault_metadata(tutorial) Vault.update_metadata(tutorial.id,metadata) @Login(store_proxy,login_view) def unpublish_tutorial(self,tutorial): """ Unpublishes a tutorial @param tutorial The tutorial to unpublish """ logging.info(tutorial.remote_id) self.store_proxy.unpublish(tutorial.remote_id) def launch_tutorial(self,tutorial): """ Lauches a tutorial @param tutorial The tutorial to launch """ pass @Login(store_proxy,login_view) def rate_tutorial(self,tutorial,rating): """ Rate the tutorial @param tutorial The tutorial to rate @param rating The new rating for the tutorial """ tutorial.rating = rating logging.info(tutorial.updated_metadata) logging.info(tutorial.remote_id) if tutorial.remote_id is not None and int(tutorial.remote_id) > 0: logging.info("this is here") self.store_proxy.rate(rating,tutorial.remote_id) self.workshop_view.refresh_content() def edit_tutorial(self,tutorial): """ Edit a tutorial @param tutorial The tutorial to edit """ pass def save_metadata(self,tutorial): """ Save the metadata of a tutorial @param tutorial The tutorial to udpate containing the new metadata """ metadata = self.tutorial_to_vault_metadata(tutorial) Vault.update_metadata(tutorial.id,metadata) self.workshop_view.refresh_content() def get_categories_for_workshop(self): """ Get all categories for selecting one in the workshop """ self.categories = self.store_proxy.get_categories() result = [] for category in self.categories: result.append(category["name"]) self.workshop_view.set_categories(result) #Function related to the store def get_categories(self): """ Get all categories of tutorial from the store """ self.categories = self.store_proxy.get_categories() result = ['all'] for category in self.categories: result.append(category["name"]) self.store_view.set_categories(result) def search_store(self,keyword,category,page=1): """ Search the store for specific tutorial @param keyword The keyword to search for @param category The category to search tutorial for @param page The page result to return """ tut_list = self.store_proxy.search(keyword,category,page) show_next = False show_prev = True if page == 1: show_prev = False if len(tut_list) == 10: next_list = self.store_proxy.search(keyword,category,page+1) if len(next_list) > 0: show_next = True tutorials = [] for tut in tut_list: tutorials.append(Tutorial(tut)) self.store_view.set_tutorial_list(tutorials) self.store_view.set_button_sensitive(show_prev,show_next) def get_tutorials_by_category(self,category,page=1): """ Get all the tutorial in a specified category @param category The category to search @param The page result to return """ for cat in self.categories: if cat["name"] == category: category = cat["id"] break tut_list = self.store_proxy.get_tutorials(category,page) show_next = False show_prev = True if page == 1: show_prev = False if len(tut_list) == 10: next_list = self.store_proxy.get_tutorials(category,page+1) if len(next_list) > 0: show_next = True tutorials = [] for tut in tut_list: tutorials.append(Tutorial(tut)) self.store_view.set_tutorial_list(tutorials) self.store_view.set_button_sensitive(show_prev,show_next) def download_tutorial(self,tutorial): """ Download a tutorial from the store @param tutorial The tutorial to download """ thread = threading.Thread(target = self.background_download,kwargs={"tutorial":tutorial}) self.dialog = WaitingDialog(thread.start,{}) thread.start() self.dialog.run() self.dialog.destroy() def background_download(self,tutorial): try: downloaded = self.store_proxy.download_tutorial(int(tutorial.remote_id)) temp_file = open('temp.zip','w') temp_file.write(downloaded.read()) temp_file.close() Vault.installTutorials(os.getcwd(),'temp.zip') temp_list = Vault.query(str(tutorial.name)) logging.info(temp_list) for tut in temp_list: tuto = Tutorial(tut) if tutorial.name == tuto.name: tuto.remote_id = tutorial.remote_id Vault.update_metadata(tuto.id,tuto.updated_metadata) except: traceback.print_exc() finally: gobject.idle_add(self.dialog.response,0) def get_popular(self): tutorials = self.store_proxy.list('Popular') result = [] for tutorial in tutorials: result.append(Tutorial(tutorial)) self.store_view.set_popular(result) def get_also_like(self): tutorials = self.store_proxy.list('Recommended') result = [] for tutorial in tutorials: result.append(Tutorial(tutorial)) self.store_view.set_also_like(result) def tutorial_to_store_metadata(self,tutorial): metadata = {} metadata['guid'] = tutorial.id metadata['name'] = tutorial.name metadata['version'] = str(tutorial.version) metadata['summary'] = tutorial.description metadata['homepage'] = "http://www.tutorius.org" metadata['description'] = tutorial.description metadata['filename'] = tutorial.name +".zip" for category in self.categories: if category["name"] == tutorial.category: metadata['cat1'] = category["id"] logging.info(metadata) return metadata def tutorial_to_vault_metadata(self,tutorial): metadata = {} for key in tutorial.updated_metadata.keys(): if key == 'activities': metadata[key] = tutorial.updated_metadata[key] else: metadata[key] = str(tutorial.updated_metadata[key]) return metadata class Tutorial(object): """ Wrapper for tutorial metadata """ def __init__(self,metadata_dict): object.__init__(self) self.__original_dict = metadata_dict self.__update_dict = {} for key in self.__original_dict.keys(): self.__update_dict[key] = self.__original_dict[key] if 'name' in self.__original_dict: self.__name = self.__original_dict['name'] else: self.__name = "" if 'version' in self.__original_dict: if self.__original_dict['version'] == '': self.__version = 0 else: self.__version = int(self.__original_dict['version']) else: self.__version = 0 if 'description' in self.__original_dict: self.__description = self.__original_dict['description'] else: self.__description = "" if 'author' in self.__original_dict: self.__author = self.__original_dict['author'] else: self.__author = "" if 'rating' in self.__original_dict: if self.__original_dict['rating'] == '': self.__rating = 0 else: self.__rating = float(self.__original_dict['rating']) else: self.__rating = 0 if 'category' in self.__original_dict: self.__category = self.__original_dict['category'] else: self.__category = "" if 'publish_state' in self.__original_dict: #I'm sorry for this temp = self.__original_dict['publish_state'] temp = temp.lower() if temp == 'false': self.__published_state = False elif temp == 'true': self.__published_state = True else: self.__published_state = None else: self.__published_state = None if 'guid' in self.__original_dict: self.__id = self.__original_dict['guid'] else: self.__id = "" if 'id' in self.__original_dict: self.__remote_id = self.__original_dict['id'] else: self.__remote_id = "" def get_name(self): return self.__name def set_name(self,name): self.__name = name self.__update_dict['name'] = name def get_version(self): return self.__version def set_version(self,version): self.__version = version self.__update_dict['version'] = version def get_description(self): return self.__description def set_description(self,description): self.__description = description self.__update_dict['description'] = description def get_author(self): return self.__author def set_author(self,author): self.__author = author self.__update_dict['author'] = author def get_rating(self): return self.__rating def set_rating(self,rating): self.__rating = rating self.__update_dict['rating'] = rating def get_category(self): return self.__category def set_category(self,category): self.__category = category self.__update_dict['category'] = category def get_published_state(self): return self.__published_state def set_published_state(self,published_state): self.__published_state = published_state self.__update_dict['published_state'] = published_state def get_id(self): return self.__id def set_id(self,id): self.__id = id self.__update_dict['guid'] = id def get_remote_id(self): return self.__remote_id def set_remote_id(self,id): self.__remote_id = id self.__update_dict['id'] = id def get_updated_metadata(self): return self.__update_dict name = property(get_name,set_name) version = property(get_version, set_version) description = property(get_description,set_description) author = property(get_author,set_author) rating = property(get_rating,set_rating) category = property(get_category,set_category) published_state = property(get_published_state,set_published_state) id = property(get_id,set_id) remote_id = property(get_remote_id, set_remote_id) updated_metadata = property(get_updated_metadata)