llassetuploadresponders.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llassetuploadresponders.h"
00035 
00036 #include "llagent.h"
00037 #include "llfloaterbuycurrency.h"
00038 #include "lleconomy.h"
00039 #include "llfilepicker.h"
00040 #include "llfocusmgr.h"
00041 #include "llnotify.h"
00042 #include "llinventorymodel.h"
00043 #include "llinventoryview.h"
00044 #include "llpermissionsflags.h"
00045 #include "llpreviewnotecard.h"
00046 #include "llpreviewscript.h"
00047 #include "llpreviewgesture.h"
00048 #include "llgesturemgr.h"
00049 #include "llscrolllistctrl.h"
00050 #include "lluploaddialog.h"
00051 #include "llviewerobject.h"
00052 #include "llviewerobjectlist.h"
00053 #include "llviewermenufile.h"
00054 #include "llviewerwindow.h"
00055 #include "viewer.h"
00056 
00057 void dialog_refresh_all();
00058 
00059 LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
00060                                                                                            const LLUUID& vfile_id,
00061                                                                                            LLAssetType::EType asset_type)
00062         : LLHTTPClient::Responder(),
00063           mPostData(post_data),
00064           mVFileID(vfile_id),
00065           mAssetType(asset_type)
00066 {
00067         if (!gVFS->getExists(vfile_id, asset_type))
00068         {
00069                 llwarns << "LLAssetUploadResponder called with nonexistant vfile_id" << llendl;
00070                 mVFileID.setNull();
00071                 mAssetType = LLAssetType::AT_NONE;
00072                 return;
00073         }
00074 }
00075 
00076 LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
00077                                                                                            const std::string& file_name)
00078         : LLHTTPClient::Responder(),
00079           mPostData(post_data),
00080           mFileName(file_name)
00081 {
00082 }
00083 
00084 LLAssetUploadResponder::~LLAssetUploadResponder()
00085 {
00086         if (!mFileName.empty())
00087         {
00088                 // Delete temp file
00089                 LLFile::remove(mFileName.c_str());
00090         }
00091 }
00092 
00093 // virtual
00094 void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
00095 {
00096         llinfos << "LLAssetUploadResponder::error " << statusNum 
00097                         << " reason: " << reason << llendl;
00098         LLStringBase<char>::format_map_t args;
00099         switch(statusNum)
00100         {
00101                 case 400:
00102                         args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
00103                         args["[REASON]"] = "Error in upload request.  Please visit "
00104                                 "http://secondlife.com/support for help fixing this problem.";
00105                         gViewerWindow->alertXml("CannotUploadReason", args);
00106                         break;
00107                 case 500:
00108                 default:
00109                         args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
00110                         args["[REASON]"] = "The server is experiencing unexpected "
00111                                 "difficulties.";
00112                         gViewerWindow->alertXml("CannotUploadReason", args);
00113                         break;
00114         }
00115         LLUploadDialog::modalUploadFinished();
00116 }
00117 
00118 //virtual 
00119 void LLAssetUploadResponder::result(const LLSD& content)
00120 {
00121         lldebugs << "LLAssetUploadResponder::result from capabilities" << llendl;
00122 
00123         std::string state = content["state"];
00124         if (state == "upload")
00125         {
00126                 uploadUpload(content);
00127         }
00128         else if (state == "complete")
00129         {
00130                 // rename file in VFS with new asset id
00131                 if (mFileName.empty())
00132                 {
00133                         // rename the file in the VFS to the actual asset id
00134                         gVFS->renameFile(mVFileID, mAssetType, content["new_asset"].asUUID(), mAssetType);
00135                 }
00136                 uploadComplete(content);
00137         }
00138         else
00139         {
00140                 uploadFailure(content);
00141         }
00142 }
00143 
00144 void LLAssetUploadResponder::uploadUpload(const LLSD& content)
00145 {
00146         std::string uploader = content["uploader"];
00147         if (mFileName.empty())
00148         {
00149                 LLHTTPClient::postFile(uploader, mVFileID, mAssetType, this);
00150         }
00151         else
00152         {
00153                 LLHTTPClient::postFile(uploader, mFileName, this);
00154         }
00155 }
00156 
00157 void LLAssetUploadResponder::uploadFailure(const LLSD& content)
00158 {
00159         std::string reason = content["state"];
00160         // deal with L$ errors
00161         if (reason == "insufficient funds")
00162         {
00163                 LLFloaterBuyCurrency::buyCurrency("Uploading costs", gGlobalEconomy->getPriceUpload());
00164         }
00165         else
00166         {
00167                 LLStringBase<char>::format_map_t args;
00168                 args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
00169                 args["[REASON]"] = content["message"].asString();
00170                 gViewerWindow->alertXml("CannotUploadReason", args);
00171         }
00172 }
00173 
00174 void LLAssetUploadResponder::uploadComplete(const LLSD& content)
00175 {
00176 }
00177 
00178 LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data,
00179                                                                                                                    const LLUUID& vfile_id,
00180                                                                                                                    LLAssetType::EType asset_type)
00181 : LLAssetUploadResponder(post_data, vfile_id, asset_type)
00182 {
00183 }
00184 
00185 LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data, const std::string& file_name)
00186 : LLAssetUploadResponder(post_data, file_name)
00187 {
00188 }
00189 
00190 //virtual 
00191 void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
00192 {
00193         lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl;
00194 
00195         LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString().c_str());
00196         LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString().c_str());
00197 
00198         // Update L$ and ownership credit information
00199         // since it probably changed on the server
00200         if (asset_type == LLAssetType::AT_TEXTURE ||
00201                 asset_type == LLAssetType::AT_SOUND ||
00202                 asset_type == LLAssetType::AT_ANIMATION)
00203         {
00204                 gMessageSystem->newMessageFast(_PREHASH_MoneyBalanceRequest);
00205                 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
00206                 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
00207                 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
00208                 gMessageSystem->nextBlockFast(_PREHASH_MoneyData);
00209                 gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
00210                 gAgent.sendReliableMessage();
00211 
00212                 LLString::format_map_t args;
00213                 args["[AMOUNT]"] = llformat("%d",gGlobalEconomy->getPriceUpload());
00214                 LLNotifyBox::showXml("UploadPayment", args);
00215         }
00216 
00217         // Actually add the upload to viewer inventory
00218         llinfos << "Adding " << content["new_inventory_item"].asUUID() << " "
00219                         << content["new_asset"].asUUID() << " to inventory." << llendl;
00220         if(mPostData["folder_id"].asUUID().notNull())
00221         {
00222                 LLPermissions perm;
00223                 U32 next_owner_perm;
00224                 perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
00225                 if (mPostData["inventory_type"].asString() == "snapshot")
00226                 {
00227                         next_owner_perm = PERM_ALL;
00228                 }
00229                 else
00230                 {
00231                         next_owner_perm = PERM_MOVE | PERM_TRANSFER;
00232                 }
00233                 perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm);
00234                 S32 creation_date_now = time_corrected();
00235                 LLPointer<LLViewerInventoryItem> item
00236                         = new LLViewerInventoryItem(content["new_inventory_item"].asUUID(),
00237                                                                                 mPostData["folder_id"].asUUID(),
00238                                                                                 perm,
00239                                                                                 content["new_asset"].asUUID(),
00240                                                                                 asset_type,
00241                                                                                 inventory_type,
00242                                                                                 mPostData["name"].asString(),
00243                                                                                 mPostData["description"].asString(),
00244                                                                                 LLSaleInfo::DEFAULT,
00245                                                                                 LLInventoryItem::II_FLAGS_NONE,
00246                                                                                 creation_date_now);
00247                 gInventory.updateItem(item);
00248                 gInventory.notifyObservers();
00249 
00250                 // Show the preview panel for textures and sounds to let
00251                 // user know that the image (or snapshot) arrived intact.
00252                 LLInventoryView* view = LLInventoryView::getActiveInventory();
00253                 if(view)
00254                 {
00255                         LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
00256                         LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback();
00257 
00258                         view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
00259                         if((LLAssetType::AT_TEXTURE == asset_type)
00260                                 || (LLAssetType::AT_SOUND == asset_type))
00261                         {
00262                                 view->getPanel()->openSelected();
00263                         }
00264                         //LLInventoryView::dumpSelectionInformation((void*)view);
00265                         // restore keyboard focus
00266                         gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
00267                 }
00268         }
00269         else
00270         {
00271                 llwarns << "Can't find a folder to put it in" << llendl;
00272         }
00273 
00274         // remove the "Uploading..." message
00275         LLUploadDialog::modalUploadFinished();
00276         
00277         // *FIX: This is a pretty big hack. What this does is check the
00278         // file picker if there are any more pending uploads. If so,
00279         // upload that file.
00280         const char* next_file = LLFilePicker::instance().getNextFile();
00281         if(next_file)
00282         {
00283                 const char* name = LLFilePicker::instance().getDirname();
00284 
00285                 LLString asset_name = name;
00286                 LLString::replaceNonstandardASCII( asset_name, '?' );
00287                 LLString::replaceChar(asset_name, '|', '?');
00288                 LLString::stripNonprintable(asset_name);
00289                 LLString::trim(asset_name);
00290 
00291                 char* asset_name_str = (char*)asset_name.c_str();
00292                 char* end_p = strrchr(asset_name_str, '.');              // strip extension if exists
00293                 if( !end_p )
00294                 {
00295                          end_p = asset_name_str + strlen( asset_name_str );                     /*Flawfinder: ignore*/
00296                 }
00297                         
00298                 S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
00299 
00300                 asset_name = asset_name.substr( 0, len );
00301 
00302                 upload_new_resource(next_file, asset_name, asset_name,
00303                                                         0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
00304         }
00305 }
00306 
00307 
00308 LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
00309                                                                                                                                  const LLUUID& vfile_id,
00310                                                                                                                                  LLAssetType::EType asset_type)
00311 : LLAssetUploadResponder(post_data, vfile_id, asset_type)
00312 {
00313 }
00314 
00315 LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
00316                                                                                                                                  const std::string& file_name)
00317 : LLAssetUploadResponder(post_data, file_name)
00318 {
00319 }
00320 
00321 //virtual 
00322 void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
00323 {
00324         llinfos << "LLUpdateAgentInventoryResponder::result from capabilities" << llendl;
00325         LLUUID item_id = mPostData["item_id"];
00326 
00327         LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(item_id);
00328         if(!item)
00329         {
00330                 llwarns << "Inventory item for " << mVFileID
00331                         << " is no longer in agent inventory." << llendl;
00332                 return;
00333         }
00334 
00335         // Update viewer inventory item
00336         LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00337         new_item->setAssetUUID(content["new_asset"].asUUID());
00338         gInventory.updateItem(new_item);
00339         gInventory.notifyObservers();
00340 
00341         llinfos << "Inventory item " << item->getName() << " saved into "
00342                 << content["new_asset"].asString() << llendl;
00343 
00344         LLInventoryType::EType inventory_type = new_item->getInventoryType();
00345         switch(inventory_type)
00346         {
00347                 case LLInventoryType::IT_NOTECARD:
00348                         {
00349 
00350                                 // Update the UI with the new asset.
00351                                 LLPreviewNotecard* nc;
00352                                 nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
00353                                 if(nc)
00354                                 {
00355                                         // *HACK: we have to delete the asset in the VFS so
00356                                         // that the viewer will redownload it. This is only
00357                                         // really necessary if the asset had to be modified by
00358                                         // the uploader, so this can be optimized away in some
00359                                         // cases. A better design is to have a new uuid if the
00360                                         // script actually changed the asset.
00361                                         if(nc->hasEmbeddedInventory())
00362                                         {
00363                                                 gVFS->removeFile(
00364                                                         content["new_asset"].asUUID(),
00365                                                         LLAssetType::AT_NOTECARD);
00366                                         }
00367                                         nc->refreshFromInventory();
00368                                 }
00369                         }
00370                         break;
00371                 case LLInventoryType::IT_LSL:
00372                         {
00373                                 // Find our window and close it if requested.
00374                                 LLPreviewLSL* preview = (LLPreviewLSL*)LLPreview::find(item_id);
00375                                 if (preview)
00376                                 {
00377                                         // Bytecode save completed
00378                                         if (content["compiled"])
00379                                         {
00380                                                 preview->callbackLSLCompileSucceeded();
00381                                         }
00382                                         else
00383                                         {
00384                                                 preview->callbackLSLCompileFailed(content["errors"]);
00385                                         }
00386                                 }
00387                         }
00388                         break;
00389 
00390                 case LLInventoryType::IT_GESTURE:
00391                         {
00392                                 // If this gesture is active, then we need to update the in-memory
00393                                 // active map with the new pointer.                             
00394                                 if (gGestureManager.isGestureActive(item_id))
00395                                 {
00396                                         LLUUID asset_id = new_item->getAssetUUID();
00397                                         gGestureManager.replaceGesture(item_id, asset_id);
00398                                         gInventory.notifyObservers();
00399                                 }                               
00400 
00401                                 //gesture will have a new asset_id
00402                                 LLPreviewGesture* previewp = (LLPreviewGesture*)LLPreview::find(item_id);
00403                                 if(previewp)
00404                                 {
00405                                         previewp->onUpdateSucceeded();  
00406                                 }                       
00407                                 
00408                         }
00409                         break;
00410                 case LLInventoryType::IT_WEARABLE:
00411                 default:
00412                         break;
00413         }
00414 }
00415 
00416 
00417 LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
00418                                                                                                                                  const LLUUID& vfile_id,
00419                                                                                                                                  LLAssetType::EType asset_type)
00420 : LLAssetUploadResponder(post_data, vfile_id, asset_type)
00421 {
00422 }
00423 
00424 LLUpdateTaskInventoryResponder::LLUpdateTaskInventoryResponder(const LLSD& post_data,
00425                                                                                                                            const std::string& file_name)
00426 : LLAssetUploadResponder(post_data, file_name)
00427 {
00428 }
00429 
00430 //virtual 
00431 void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
00432 {
00433         llinfos << "LLUpdateTaskInventoryResponder::result from capabilities" << llendl;
00434         LLUUID item_id = mPostData["item_id"];
00435         LLUUID task_id = mPostData["task_id"];
00436 
00437         LLViewerObject* object = gObjectList.findObject(task_id);
00438         if (!object)
00439         {
00440                 llwarns << "LLUpdateTaskInventoryResponder::uploadComplete task " << task_id
00441                         << " no longer exist." << llendl;
00442                 return;
00443         }
00444         LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(item_id);
00445         if (!item)
00446         {
00447                 llwarns << "LLUpdateTaskInventoryResponder::uploadComplete item "
00448                         << item_id << " is no longer in task " << task_id
00449                         << "'s inventory." << llendl;
00450                 return;
00451         }
00452         LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
00453         // Update Viewer inventory
00454         object->updateViewerInventoryAsset(new_item, content["new_asset"]);
00455         dialog_refresh_all();
00456         
00457         LLInventoryType::EType inventory_type = new_item->getInventoryType();
00458         switch(inventory_type)
00459         {
00460                 case LLInventoryType::IT_NOTECARD:
00461                         {
00462 
00463                                 // Update the UI with the new asset.
00464                                 LLPreviewNotecard* nc;
00465                                 nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
00466                                 if(nc)
00467                                 {
00468                                         // *HACK: we have to delete the asset in the VFS so
00469                                         // that the viewer will redownload it. This is only
00470                                         // really necessary if the asset had to be modified by
00471                                         // the uploader, so this can be optimized away in some
00472                                         // cases. A better design is to have a new uuid if the
00473                                         // script actually changed the asset.
00474                                         if(nc->hasEmbeddedInventory())
00475                                         {
00476                                                 gVFS->removeFile(
00477                                                         content["new_asset"].asUUID(),
00478                                                         LLAssetType::AT_NOTECARD);
00479                                         }
00480 
00481                                         nc->refreshFromInventory();
00482                                 }
00483                         }
00484                         break;
00485                 case LLInventoryType::IT_LSL:
00486                         {
00487                                 LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id);
00488                                 if (preview)
00489                                 {
00490                                         // Bytecode save completed
00491                                         if (content["compiled"])
00492                                         {
00493                                                 preview->callbackLSLCompileSucceeded(
00494                                                         task_id,
00495                                                         item_id,
00496                                                         mPostData["is_script_running"]);
00497                                         }
00498                                         else
00499                                         {
00500                                                 preview->callbackLSLCompileFailed(content["errors"]);
00501                                         }
00502                                 }
00503                         }
00504                         break;
00505                 case LLInventoryType::IT_WEARABLE:
00506                 default:
00507                         break;
00508         }
00509 }

Generated on Thu Jul 1 06:08:19 2010 for Second Life Viewer by  doxygen 1.4.7