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

Generated on Fri May 16 08:33:15 2008 for SecondLife by  doxygen 1.5.5