Here's the Gurobi code to solve the optimization problem:

```python
import gurobipy as gp

try:
    # Create a new model
    m = gp.Model("optimization_model")

    # Create variables
    scissors = m.addVar(vtype=gp.GRB.INTEGER, name="scissors")
    smoke_detectors = m.addVar(vtype=gp.GRB.INTEGER, name="smoke_detectors")
    hole_punches = m.addVar(vtype=gp.GRB.INTEGER, name="hole_punches")
    mechanical_pencils = m.addVar(vtype=gp.GRB.INTEGER, name="mechanical_pencils")

    # Set objective function
    m.setObjective(5.78 * scissors + 4.79 * smoke_detectors + 1.44 * hole_punches + 8.87 * mechanical_pencils, gp.GRB.MAXIMIZE)

    # Add constraints
    m.addConstr(22 * scissors + 21 * smoke_detectors + 28 * hole_punches + 9 * mechanical_pencils <= 294, "sustainability_score")  # Resource r0
    m.addConstr(3 * scissors + 26 * smoke_detectors + 11 * hole_punches + 6 * mechanical_pencils <= 373, "storage_space")  # Resource r1

    m.addConstr(26 * smoke_detectors + 11 * hole_punches >= 75, "storage_sd_hp")
    m.addConstr(26 * smoke_detectors + 6 * mechanical_pencils >= 77, "storage_sd_mp")
    m.addConstr(3 * scissors + 26 * smoke_detectors + 6 * mechanical_pencils >= 93, "storage_s_sd_mp")

    m.addConstr(21 * smoke_detectors + 28 * hole_punches <= 105, "sustainability_sd_hp")
    m.addConstr(28 * hole_punches + 9 * mechanical_pencils <= 122, "sustainability_hp_mp")
    m.addConstr(22 * scissors + 9 * mechanical_pencils <= 144, "sustainability_s_mp")
    m.addConstr(22 * scissors + 28 * hole_punches <= 140, "sustainability_s_hp")
    m.addConstr(22 * scissors + 28 * hole_punches + 9 * mechanical_pencils <= 93, "sustainability_s_hp_mp")
    m.addConstr(22 * scissors + 21 * smoke_detectors + 28 * hole_punches + 9 * mechanical_pencils <= 93, "sustainability_all")

    m.addConstr(3 * scissors + 26 * smoke_detectors <= 327, "storage_s_sd")
    m.addConstr(3 * scissors + 6 * mechanical_pencils <= 157, "storage_s_mp")
    m.addConstr(3 * scissors + 11 * hole_punches <= 251, "storage_s_hp")
    m.addConstr(11 * hole_punches + 6 * mechanical_pencils <= 175, "storage_hp_mp")
    m.addConstr(3 * scissors + 26 * smoke_detectors + 6 * mechanical_pencils <= 184, "storage_s_sd_mp_ub")
    m.addConstr(3 * scissors + 26 * smoke_detectors + 11 * hole_punches + 6 * mechanical_pencils <= 184, "storage_all_ub")


    # Optimize model
    m.optimize()

    if m.status == gp.GRB.OPTIMAL:
        print('Obj: %g' % m.objVal)
        for v in m.getVars():
            print('%s %g' % (v.varName, v.x))
    elif m.status == gp.GRB.INFEASIBLE:
        print("The model is infeasible.")
    else:
        print("Optimization ended with status:", m.status)


except gp.GurobiError as e:
    print('Error code ' + str(e.errno) + ': ' + str(e))

except AttributeError:
    print('Encountered an attribute error')
```
